#!/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 [TextParameter(x) for x in ['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 [TextParameter(x) for x in ['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'

###

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

