#!/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(object):
    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(object):
  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(object):
    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(object):
    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(object):
    @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

