from __future__ import print_function
try:
    from http.server import HTTPServer, SimpleHTTPRequestHandler
except ImportError:
    from BaseHTTPServer import HTTPServer
    from SimpleHTTPServer import SimpleHTTPRequestHandler
import os
import sys
try:
    from urlparse import urlparse
    from urllib import unquote
except ImportError:
    from urllib.parse import urlparse, unquote

import posixpath

if sys.version_info.major >= 3:
    from io import StringIO, BytesIO
else:
    from io import BytesIO, BytesIO as StringIO

import re
import shutil
import threading
import time
import socket
import itertools

import Reporter
try:
    import configparser
except ImportError:
    import ConfigParser as configparser

###
# Various patterns matched or replaced by server.

kReportFileRE = re.compile('(.*/)?report-(.*)\\.html')

kBugKeyValueRE = re.compile('<!-- BUG([^ ]*) (.*) -->')

#  <!-- REPORTPROBLEM file="crashes/clang_crash_ndSGF9.mi" stderr="crashes/clang_crash_ndSGF9.mi.stderr.txt" info="crashes/clang_crash_ndSGF9.mi.info" -->

kReportCrashEntryRE = re.compile('<!-- REPORTPROBLEM (.*?)-->')
kReportCrashEntryKeyValueRE = re.compile(' ?([^=]+)="(.*?)"')

kReportReplacements = []

# Add custom javascript.
kReportReplacements.append((re.compile('<!-- SUMMARYENDHEAD -->'), """\
<script language="javascript" type="text/javascript">
function load(url) {
  if (window.XMLHttpRequest) {
    req = new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    req = new ActiveXObject("Microsoft.XMLHTTP");
  }
  if (req != undefined) {
    req.open("GET", url, true);
    req.send("");
  }
}
</script>"""))

# Insert additional columns.
kReportReplacements.append((re.compile('<!-- REPORTBUGCOL -->'), 
                            '<td></td><td></td>'))

# Insert report bug and open file links.
kReportReplacements.append((re.compile('<!-- REPORTBUG id="report-(.*)\\.html" -->'),
                            ('<td class="Button"><a href="report/\\1">Report Bug</a></td>' + 
                             '<td class="Button"><a href="javascript:load(\'open/\\1\')">Open File</a></td>')))

kReportReplacements.append((re.compile('<!-- REPORTHEADER -->'),
                                       '<h3><a href="/">Summary</a> > Report %(report)s</h3>'))

kReportReplacements.append((re.compile('<!-- REPORTSUMMARYEXTRA -->'),
                            '<td class="Button"><a href="report/%(report)s">Report Bug</a></td>'))

# Insert report crashes link.

# Disabled for the time being until we decide exactly when this should
# be enabled. Also the radar reporter needs to be fixed to report
# multiple files.

#kReportReplacements.append((re.compile('<!-- REPORTCRASHES -->'),
#                            '<br>These files will automatically be attached to ' +
#                            'reports filed here: <a href="report_crashes">Report Crashes</a>.'))

###
# Other simple parameters

kShare = posixpath.join(posixpath.dirname(__file__), '../share/scan-view')
kConfigPath = os.path.expanduser('~/.scanview.cfg')

###

__version__ = "0.1"

__all__ = ["create_server"]

class ReporterThread(threading.Thread):
    def __init__(self, report, reporter, parameters, server):
        threading.Thread.__init__(self)
        self.report = report
        self.server = server
        self.reporter = reporter
        self.parameters = parameters
        self.success = False
        self.status = None

    def run(self):
        result = None
        try:
            if self.server.options.debug:
                print("%s: SERVER: submitting bug."%(sys.argv[0],), file=sys.stderr)
            self.status = self.reporter.fileReport(self.report, self.parameters)
            self.success = True
            time.sleep(3)
            if self.server.options.debug:
                print("%s: SERVER: submission complete."%(sys.argv[0],), file=sys.stderr)
        except Reporter.ReportFailure as e:
            self.status = e.value
        except Exception as e:
            s = StringIO()
            import traceback
            print('<b>Unhandled Exception</b><br><pre>', file=s)
            traceback.print_exc(file=s)
            print('</pre>', file=s)
            self.status = s.getvalue()

class ScanViewServer(HTTPServer):
    def __init__(self, address, handler, root, reporters, options):
        HTTPServer.__init__(self, address, handler)
        self.root = root
        self.reporters = reporters
        self.options = options        
        self.halted = False
        self.config = None
        self.load_config()

    def load_config(self):
        self.config = configparser.RawConfigParser()

        # Add defaults
        self.config.add_section('ScanView')
        for r in self.reporters:
            self.config.add_section(r.getName())
            for p in r.getParameters():
              if p.saveConfigValue():
                self.config.set(r.getName(), p.getName(), '')

        # Ignore parse errors
        try:
            self.config.read([kConfigPath])
        except:
            pass

        # Save on exit
        import atexit
        atexit.register(lambda: self.save_config())
        
    def save_config(self):
        # Ignore errors (only called on exit).
        try:
            f = open(kConfigPath,'w')
            self.config.write(f)
            f.close()
        except:
            pass
        
    def halt(self):
        self.halted = True
        if self.options.debug:
            print("%s: SERVER: halting." % (sys.argv[0],), file=sys.stderr)

    def serve_forever(self):
        while not self.halted:
            if self.options.debug > 1:
                print("%s: SERVER: waiting..." % (sys.argv[0],), file=sys.stderr)
            try:
                self.handle_request()
            except OSError as e:
                print('OSError',e.errno)

    def finish_request(self, request, client_address):
        if self.options.autoReload:
            import ScanView
            self.RequestHandlerClass = reload(ScanView).ScanViewRequestHandler
        HTTPServer.finish_request(self, request, client_address)

    def handle_error(self, request, client_address):
        # Ignore socket errors
        info = sys.exc_info()
        if info and isinstance(info[1], socket.error):
            if self.options.debug > 1:
                print("%s: SERVER: ignored socket error." % (sys.argv[0],), file=sys.stderr)
            return
        HTTPServer.handle_error(self, request, client_address)

# Borrowed from Quixote, with simplifications.
def parse_query(qs, fields=None):
    if fields is None:
        fields = {}
    for chunk in (_f for _f in qs.split('&') if _f):
        if '=' not in chunk:
            name = chunk
            value = ''
        else:
            name, value = chunk.split('=', 1)
        name = unquote(name.replace('+', ' '))
        value = unquote(value.replace('+', ' '))
        item = fields.get(name)
        if item is None:
            fields[name] = [value]
        else:
            item.append(value)
    return fields

class ScanViewRequestHandler(SimpleHTTPRequestHandler):
    server_version = "ScanViewServer/" + __version__
    dynamic_mtime = time.time()

    def do_HEAD(self):
        try:
            SimpleHTTPRequestHandler.do_HEAD(self)
        except Exception as e:
            self.handle_exception(e)
            
    def do_GET(self):
        try:
            SimpleHTTPRequestHandler.do_GET(self)
        except Exception as e:
            self.handle_exception(e)
            
    def do_POST(self):
        """Serve a POST request."""
        try:
            length = self.headers.getheader('content-length') or "0"
            try:
                length = int(length)
            except:
                length = 0
            content = self.rfile.read(length)
            fields = parse_query(content)
            f = self.send_head(fields)
            if f:
                self.copyfile(f, self.wfile)
                f.close()
        except Exception as e:
            self.handle_exception(e)            

    def log_message(self, format, *args):
        if self.server.options.debug:
            sys.stderr.write("%s: SERVER: %s - - [%s] %s\n" %
                             (sys.argv[0],
                              self.address_string(),
                              self.log_date_time_string(),
                              format%args))

    def load_report(self, report):
        path = os.path.join(self.server.root, 'report-%s.html'%report)
        data = open(path).read()
        keys = {}
        for item in kBugKeyValueRE.finditer(data):
            k,v = item.groups()
            keys[k] = v
        return keys

    def load_crashes(self):
        path = posixpath.join(self.server.root, 'index.html')
        data = open(path).read()
        problems = []
        for item in kReportCrashEntryRE.finditer(data):
            fieldData = item.group(1)
            fields = dict([i.groups() for i in 
                           kReportCrashEntryKeyValueRE.finditer(fieldData)])
            problems.append(fields)
        return problems

    def handle_exception(self, exc):
        import traceback
        s = StringIO()
        print("INTERNAL ERROR\n", file=s)
        traceback.print_exc(file=s)
        f = self.send_string(s.getvalue(), 'text/plain')
        if f:
            self.copyfile(f, self.wfile)
            f.close()        
            
    def get_scalar_field(self, name):
        if name in self.fields:
            return self.fields[name][0]
        else:
            return None

    def submit_bug(self, c):
        title = self.get_scalar_field('title')
        description = self.get_scalar_field('description')
        report = self.get_scalar_field('report')
        reporterIndex = self.get_scalar_field('reporter')
        files = []
        for fileID in self.fields.get('files',[]):
            try:
                i = int(fileID)
            except:
                i = None
            if i is None or i<0 or i>=len(c.files):
                return (False, 'Invalid file ID')
            files.append(c.files[i])
        
        if not title:
            return (False, "Missing title.")
        if not description:
            return (False, "Missing description.")
        try:
            reporterIndex = int(reporterIndex)
        except:
            return (False, "Invalid report method.")
        
        # Get the reporter and parameters.
        reporter = self.server.reporters[reporterIndex]
        parameters = {}
        for o in reporter.getParameters():
            name = '%s_%s'%(reporter.getName(),o.getName())
            if name not in self.fields:
                return (False, 
                        'Missing field "%s" for %s report method.'%(name,
                                                                    reporter.getName()))
            parameters[o.getName()] = self.get_scalar_field(name)

        # Update config defaults.
        if report != 'None':
            self.server.config.set('ScanView', 'reporter', reporterIndex)
            for o in reporter.getParameters():
              if o.saveConfigValue():
                name = o.getName()
                self.server.config.set(reporter.getName(), name, parameters[name])

        # Create the report.
        bug = Reporter.BugReport(title, description, files)

        # Kick off a reporting thread.
        t = ReporterThread(bug, reporter, parameters, self.server)
        t.start()

        # Wait for thread to die...
        while t.isAlive():
            time.sleep(.25)
        submitStatus = t.status

        return (t.success, t.status)

    def send_report_submit(self):
        report = self.get_scalar_field('report')
        c = self.get_report_context(report)
        if c.reportSource is None:
            reportingFor = "Report Crashes > "
            fileBug = """\
<a href="/report_crashes">File Bug</a> > """%locals()
        else:
            reportingFor = '<a href="/%s">Report %s</a> > ' % (c.reportSource, 
                                                                   report)
            fileBug = '<a href="/report/%s">File Bug</a> > ' % report
        title = self.get_scalar_field('title')
        description = self.get_scalar_field('description')

        res,message = self.submit_bug(c)

        if res:
            statusClass = 'SubmitOk'
            statusName = 'Succeeded'
        else:
            statusClass = 'SubmitFail'
            statusName = 'Failed'

        result = """
<head>
  <title>Bug Submission</title>
  <link rel="stylesheet" type="text/css" href="/scanview.css" />
</head>
<body>
<h3>
<a href="/">Summary</a> > 
%(reportingFor)s
%(fileBug)s
Submit</h3>
<form name="form" action="">
<table class="form">
<tr><td>
<table class="form_group">
<tr>
  <td class="form_clabel">Title:</td>
  <td class="form_value">
    <input type="text" name="title" size="50" value="%(title)s" disabled>
  </td>
</tr>
<tr>
  <td class="form_label">Description:</td>
  <td class="form_value">
<textarea rows="10" cols="80" name="description" disabled>
%(description)s
</textarea>
  </td>
</table>
</td></tr>
</table>
</form>
<h1 class="%(statusClass)s">Submission %(statusName)s</h1>
%(message)s
<p>
<hr>
<a href="/">Return to Summary</a>
</body>
</html>"""%locals()
        return self.send_string(result)

    def send_open_report(self, report):
        try:
            keys = self.load_report(report)
        except IOError:
            return self.send_error(400, 'Invalid report.')

        file = keys.get('FILE')
        if not file or not posixpath.exists(file):
            return self.send_error(400, 'File does not exist: "%s"' % file)

        import startfile
        if self.server.options.debug:
            print('%s: SERVER: opening "%s"'%(sys.argv[0],
                                                            file), file=sys.stderr)

        status = startfile.open(file)
        if status:
            res = 'Opened: "%s"' % file
        else:
            res = 'Open failed: "%s"' % file

        return self.send_string(res, 'text/plain')

    def get_report_context(self, report):
        class Context(object):
            pass
        if report is None or report == 'None':
            data = self.load_crashes()
            # Don't allow empty reports.
            if not data:
                raise ValueError('No crashes detected!')
            c = Context()
            c.title = 'clang static analyzer failures'

            stderrSummary = ""
            for item in data:
                if 'stderr' in item:
                    path = posixpath.join(self.server.root, item['stderr'])
                    if os.path.exists(path):
                        lns = itertools.islice(open(path), 0, 10)
                        stderrSummary += '%s\n--\n%s' % (item.get('src', 
                                                                  '<unknown>'),
                                                         ''.join(lns))

            c.description = """\
The clang static analyzer failed on these inputs:
%s

STDERR Summary
--------------
%s
""" % ('\n'.join([item.get('src','<unknown>') for item in data]),
       stderrSummary)
            c.reportSource = None
            c.navMarkup = "Report Crashes > "
            c.files = []
            for item in data:                
                c.files.append(item.get('src',''))
                c.files.append(posixpath.join(self.server.root,
                                              item.get('file','')))
                c.files.append(posixpath.join(self.server.root,
                                              item.get('clangfile','')))
                c.files.append(posixpath.join(self.server.root,
                                              item.get('stderr','')))
                c.files.append(posixpath.join(self.server.root,
                                              item.get('info','')))
            # Just in case something failed, ignore files which don't
            # exist.
            c.files = [f for f in c.files
                       if os.path.exists(f) and os.path.isfile(f)]
        else:
            # Check that this is a valid report.            
            path = posixpath.join(self.server.root, 'report-%s.html' % report)
            if not posixpath.exists(path):
                raise ValueError('Invalid report ID')
            keys = self.load_report(report)
            c = Context()
            c.title = keys.get('DESC','clang error (unrecognized')
            c.description = """\
Bug reported by the clang static analyzer.

Description: %s
File: %s
Line: %s
"""%(c.title, keys.get('FILE','<unknown>'), keys.get('LINE', '<unknown>'))
            c.reportSource = 'report-%s.html' % report
            c.navMarkup = """<a href="/%s">Report %s</a> > """ % (c.reportSource,
                                                                  report)

            c.files = [path]
        return c

    def send_report(self, report, configOverrides=None):
        def getConfigOption(section, field):            
            if (configOverrides is not None and
                section in configOverrides and
                field in configOverrides[section]):
                return configOverrides[section][field]
            return self.server.config.get(section, field)

        # report is None is used for crashes
        try:
            c = self.get_report_context(report)
        except ValueError as e:
            return self.send_error(400, e.message)

        title = c.title
        description= c.description
        reportingFor = c.navMarkup
        if c.reportSource is None:
            extraIFrame = ""
        else:
            extraIFrame = """\
<iframe src="/%s" width="100%%" height="40%%"
        scrolling="auto" frameborder="1">
  <a href="/%s">View Bug Report</a>
</iframe>""" % (c.reportSource, c.reportSource)

        reporterSelections = []
        reporterOptions = []

        try:
            active = int(getConfigOption('ScanView','reporter'))
        except:
            active = 0
        for i,r in enumerate(self.server.reporters):
            selected = (i == active)
            if selected:
                selectedStr = ' selected'
            else:
                selectedStr = ''
            reporterSelections.append('<option value="%d"%s>%s</option>'%(i,selectedStr,r.getName()))
            options = '\n'.join([ o.getHTML(r,title,getConfigOption) for o in r.getParameters()])
            display = ('none','')[selected]
            reporterOptions.append("""\
<tr id="%sReporterOptions" style="display:%s">
  <td class="form_label">%s Options</td>
  <td class="form_value">
    <table class="form_inner_group">
%s
    </table>
  </td>
</tr>
"""%(r.getName(),display,r.getName(),options))
        reporterSelections = '\n'.join(reporterSelections)
        reporterOptionsDivs = '\n'.join(reporterOptions)
        reportersArray = '[%s]'%(','.join([repr(r.getName()) for r in self.server.reporters]))

        if c.files:
            fieldSize = min(5, len(c.files))
            attachFileOptions = '\n'.join(["""\
<option value="%d" selected>%s</option>""" % (i,v) for i,v in enumerate(c.files)])
            attachFileRow = """\
<tr>
  <td class="form_label">Attach:</td>
  <td class="form_value">
<select style="width:100%%" name="files" multiple size=%d>
%s
</select>
  </td>
</tr>
""" % (min(5, len(c.files)), attachFileOptions)
        else:
            attachFileRow = ""

        result = """<html>
<head>
  <title>File Bug</title>
  <link rel="stylesheet" type="text/css" href="/scanview.css" />
</head>
<script language="javascript" type="text/javascript">
var reporters = %(reportersArray)s;
function updateReporterOptions() {
  index = document.getElementById('reporter').selectedIndex;
  for (var i=0; i < reporters.length; ++i) {
    o = document.getElementById(reporters[i] + "ReporterOptions");
    if (i == index) {
      o.style.display = "";
    } else {
      o.style.display = "none";
    }
  }
}
</script>
<body onLoad="updateReporterOptions()">
<h3>
<a href="/">Summary</a> > 
%(reportingFor)s
File Bug</h3>
<form name="form" action="/report_submit" method="post">
<input type="hidden" name="report" value="%(report)s">

<table class="form">
<tr><td>
<table class="form_group">
<tr>
  <td class="form_clabel">Title:</td>
  <td class="form_value">
    <input type="text" name="title" size="50" value="%(title)s">
  </td>
</tr>
<tr>
  <td class="form_label">Description:</td>
  <td class="form_value">
<textarea rows="10" cols="80" name="description">
%(description)s
</textarea>
  </td>
</tr>

%(attachFileRow)s

</table>
<br>
<table class="form_group">
<tr>
  <td class="form_clabel">Method:</td>
  <td class="form_value">
    <select id="reporter" name="reporter" onChange="updateReporterOptions()">
    %(reporterSelections)s
    </select>
  </td>
</tr>
%(reporterOptionsDivs)s
</table>
<br>
</td></tr>
<tr><td class="form_submit">
  <input align="right" type="submit" name="Submit" value="Submit">
</td></tr>
</table>
</form>

%(extraIFrame)s

</body>
</html>"""%locals()

        return self.send_string(result)

    def send_head(self, fields=None):
        if (self.server.options.onlyServeLocal and
            self.client_address[0] != '127.0.0.1'):
            return self.send_error(401, 'Unauthorized host.')

        if fields is None:
            fields = {}
        self.fields = fields

        o = urlparse(self.path)
        self.fields = parse_query(o.query, fields)
        path = posixpath.normpath(unquote(o.path))

        # Split the components and strip the root prefix.
        components = path.split('/')[1:]
        
        # Special case some top-level entries.
        if components:
            name = components[0]
            if len(components)==2:
                if name=='report':
                    return self.send_report(components[1])
                elif name=='open':
                    return self.send_open_report(components[1])
            elif len(components)==1:
                if name=='quit':
                    self.server.halt()
                    return self.send_string('Goodbye.', 'text/plain')
                elif name=='report_submit':
                    return self.send_report_submit()
                elif name=='report_crashes':
                    overrides = { 'ScanView' : {},
                                  'Radar' : {},
                                  'Email' : {} }
                    for i,r in enumerate(self.server.reporters):
                        if r.getName() == 'Radar':
                            overrides['ScanView']['reporter'] = i
                            break
                    overrides['Radar']['Component'] = 'llvm - checker'
                    overrides['Radar']['Component Version'] = 'X'
                    return self.send_report(None, overrides)
                elif name=='favicon.ico':
                    return self.send_path(posixpath.join(kShare,'bugcatcher.ico'))
        
        # Match directory entries.
        if components[-1] == '':
            components[-1] = 'index.html'

        relpath = '/'.join(components)
        path = posixpath.join(self.server.root, relpath)

        if self.server.options.debug > 1:
            print('%s: SERVER: sending path "%s"'%(sys.argv[0],
                                                                 path), file=sys.stderr)
        return self.send_path(path)

    def send_404(self):
        self.send_error(404, "File not found")
        return None

    def send_path(self, path):
        # If the requested path is outside the root directory, do not open it
        rel = os.path.abspath(path)
        if not rel.startswith(os.path.abspath(self.server.root)):
          return self.send_404()
        
        ctype = self.guess_type(path)
        if ctype.startswith('text/'):
            # Patch file instead
            return self.send_patched_file(path, ctype)
        else:
            mode = 'rb'
        try:
            f = open(path, mode)
        except IOError:
            return self.send_404()
        return self.send_file(f, ctype)

    def send_file(self, f, ctype):
        # Patch files to add links, but skip binary files.
        self.send_response(200)
        self.send_header("Content-type", ctype)
        fs = os.fstat(f.fileno())
        self.send_header("Content-Length", str(fs[6]))
        self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
        self.end_headers()
        return f

    def send_string(self, s, ctype='text/html', headers=True, mtime=None):
        encoded_s = s.encode()
        if headers:
            self.send_response(200)
            self.send_header("Content-type", ctype)
            self.send_header("Content-Length", str(len(encoded_s)))
            if mtime is None:
                mtime = self.dynamic_mtime
            self.send_header("Last-Modified", self.date_time_string(mtime))
            self.end_headers()
        return BytesIO(encoded_s)

    def send_patched_file(self, path, ctype):
        # Allow a very limited set of variables. This is pretty gross.
        variables = {}
        variables['report'] = ''
        m = kReportFileRE.match(path)
        if m:
            variables['report'] = m.group(2)

        try:
            f = open(path,'rb')
        except IOError:
            return self.send_404()
        fs = os.fstat(f.fileno())
        data = f.read().decode('utf-8')
        for a,b in kReportReplacements:
            data = a.sub(b % variables, data)
        return self.send_string(data, ctype, mtime=fs.st_mtime)


def create_server(address, options, root):
    import Reporter

    reporters = Reporter.getReporters()

    return ScanViewServer(address, ScanViewRequestHandler,
                          root,
                          reporters,
                          options)
