#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Methods for reporting bugs."""

import subprocess, sys, os

__all__ = ['ReportFailure', 'BugReport', 'getReporters']

#

class ReportFailure(Exception):
    """Generic exception for failures in bug reporting."""
    def __init__(self, value):        
        self.value = value

# Collect information about a bug.

class BugReport:
    def __init__(self, title, description, files):
        self.title = title
        self.description = description
        self.files = files

# Reporter interfaces.

import os

import email, mimetypes, smtplib
from email import encoders
from email.message import Message
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

#===------------------------------------------------------------------------===#
# ReporterParameter
#===------------------------------------------------------------------------===#

class ReporterParameter:
  def __init__(self, n):
    self.name = n
  def getName(self):
    return self.name
  def getValue(self,r,bugtype,getConfigOption):
     return getConfigOption(r.getName(),self.getName())
  def saveConfigValue(self):
    return True

class TextParameter (ReporterParameter):
  def getHTML(self,r,bugtype,getConfigOption):
    return """\
<tr>
<td class="form_clabel">%s:</td>
<td class="form_value"><input type="text" name="%s_%s" value="%s"></td>
</tr>"""%(self.getName(),r.getName(),self.getName(),self.getValue(r,bugtype,getConfigOption))

class SelectionParameter (ReporterParameter):
  def __init__(self, n, values):
    ReporterParameter.__init__(self,n)
    self.values = values
    
  def getHTML(self,r,bugtype,getConfigOption):
    default = self.getValue(r,bugtype,getConfigOption)
    return """\
<tr>
<td class="form_clabel">%s:</td><td class="form_value"><select name="%s_%s">
%s
</select></td>"""%(self.getName(),r.getName(),self.getName(),'\n'.join(["""\
<option value="%s"%s>%s</option>"""%(o[0],
                                     o[0] == default and ' selected="selected"' or '',
                                     o[1]) for o in self.values]))

#===------------------------------------------------------------------------===#
# Reporters
#===------------------------------------------------------------------------===#

class EmailReporter:
    def getName(self):
        return 'Email'

    def getParameters(self):
        return map(lambda x:TextParameter(x),['To', 'From', 'SMTP Server', 'SMTP Port'])

    # Lifted from python email module examples.
    def attachFile(self, outer, path):
        # Guess the content type based on the file's extension.  Encoding
        # will be ignored, although we should check for simple things like
        # gzip'd or compressed files.
        ctype, encoding = mimetypes.guess_type(path)
        if ctype is None or encoding is not None:
            # No guess could be made, or the file is encoded (compressed), so
            # use a generic bag-of-bits type.
            ctype = 'application/octet-stream'
        maintype, subtype = ctype.split('/', 1)
        if maintype == 'text':
            fp = open(path)
            # Note: we should handle calculating the charset
            msg = MIMEText(fp.read(), _subtype=subtype)
            fp.close()
        else:
            fp = open(path, 'rb')
            msg = MIMEBase(maintype, subtype)
            msg.set_payload(fp.read())
            fp.close()
            # Encode the payload using Base64
            encoders.encode_base64(msg)
        # Set the filename parameter
        msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(path))
        outer.attach(msg)

    def fileReport(self, report, parameters):
        mainMsg = """\
BUG REPORT
---
Title: %s
Description: %s
"""%(report.title, report.description)

        if not parameters.get('To'):
            raise ReportFailure('No "To" address specified.')
        if not parameters.get('From'):
            raise ReportFailure('No "From" address specified.')

        msg = MIMEMultipart()
        msg['Subject'] = 'BUG REPORT: %s'%(report.title)
        # FIXME: Get config parameters
        msg['To'] = parameters.get('To')
        msg['From'] = parameters.get('From')
        msg.preamble = mainMsg

        msg.attach(MIMEText(mainMsg, _subtype='text/plain'))
        for file in report.files:
            self.attachFile(msg, file)

        try:
            s = smtplib.SMTP(host=parameters.get('SMTP Server'),
                             port=parameters.get('SMTP Port'))
            s.sendmail(msg['From'], msg['To'], msg.as_string())
            s.close()
        except:
            raise ReportFailure('Unable to send message via SMTP.')

        return "Message sent!"

class BugzillaReporter:
    def getName(self):
        return 'Bugzilla'
    
    def getParameters(self):
        return map(lambda x:TextParameter(x),['URL','Product'])

    def fileReport(self, report, parameters):
        raise NotImplementedError
 

class RadarClassificationParameter(SelectionParameter):
  def __init__(self):
    SelectionParameter.__init__(self,"Classification",
            [['1', 'Security'], ['2', 'Crash/Hang/Data Loss'],
             ['3', 'Performance'], ['4', 'UI/Usability'], 
             ['6', 'Serious Bug'], ['7', 'Other']])

  def saveConfigValue(self):
    return False
    
  def getValue(self,r,bugtype,getConfigOption):
    if bugtype.find("leak") != -1:
      return '3'
    elif bugtype.find("dereference") != -1:
      return '2'
    elif bugtype.find("missing ivar release") != -1:
      return '3'
    else:
      return '7'

class RadarReporter:
    @staticmethod
    def isAvailable():
        # FIXME: Find this .scpt better
        path = os.path.join(os.path.dirname(__file__),'../share/scan-view/GetRadarVersion.scpt')
        try:
          p = subprocess.Popen(['osascript',path], 
          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except:
            return False
        data,err = p.communicate()
        res = p.wait()
        # FIXME: Check version? Check for no errors?
        return res == 0

    def getName(self):
        return 'Radar'

    def getParameters(self):
        return [ TextParameter('Component'), TextParameter('Component Version'),
                 RadarClassificationParameter() ]

    def fileReport(self, report, parameters):
        component = parameters.get('Component', '')
        componentVersion = parameters.get('Component Version', '')
        classification = parameters.get('Classification', '')
        personID = ""
        diagnosis = ""
        config = ""

        if not component.strip():
            component = 'Bugs found by clang Analyzer'
        if not componentVersion.strip():
            componentVersion = 'X'

        script = os.path.join(os.path.dirname(__file__),'../share/scan-view/FileRadar.scpt')
        args = ['osascript', script, component, componentVersion, classification, personID, report.title,
                report.description, diagnosis, config] + map(os.path.abspath, report.files)
#        print >>sys.stderr, args
        try:
          p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except:
            raise ReportFailure("Unable to file radar (AppleScript failure).")
        data, err = p.communicate()
        res = p.wait()

        if res:
            raise ReportFailure("Unable to file radar (AppleScript failure).")

        try:
            values = eval(data)
        except:
            raise ReportFailure("Unable to process radar results.")

        # We expect (int: bugID, str: message)
        if len(values) != 2 or not isinstance(values[0], int):
            raise ReportFailure("Unable to process radar results.")

        bugID,message = values
        bugID = int(bugID)
        
        if not bugID:
            raise ReportFailure(message)
        
        return "Filed: <a href=\"rdar://%d/\">%d</a>"%(bugID,bugID)

###

def getReporters():
    reporters = []
    if RadarReporter.isAvailable():
        reporters.append(RadarReporter())
    reporters.append(EmailReporter())
    return reporters

