# Copyright (c) 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import datetime
import json
import os
import tempfile
import time
import urllib
import urllib2

import perf_insights_project

import webapp2
from webapp2 import Route

from perf_insights.mre import cloud_storage
from perf_insights.mre import local_directory_corpus_driver
from perf_insights.mre import corpus_query
from perf_insights.mre import map_runner
from perf_insights.mre import job as job_module
from perf_insights.mre import json_output_formatter

MAX_TRACES = 10000


def _RelPathToUnixPath(p):
  return p.replace(os.sep, '/')

class TestListHandler(webapp2.RequestHandler):
  def get(self, *args, **kwargs): # pylint: disable=unused-argument
    project = perf_insights_project.PerfInsightsProject()
    test_relpaths = ['/' + _RelPathToUnixPath(x)
                     for x in project.FindAllTestModuleRelPaths()]

    tests = {'test_relpaths': test_relpaths}
    tests_as_json = json.dumps(tests)
    self.response.content_type = 'application/json'
    return self.response.write(tests_as_json)


class RunMapFunctionHandler(webapp2.RequestHandler):

  def post(self, *args, **kwargs):  # pylint: disable=unused-argument
    job_dict = json.loads(self.request.body)

    job = job_module.Job.FromDict(job_dict)

    job_with_filenames = job_module.Job(
        job.map_function_handle.ConvertHrefsToAbsFilenames(self.app))

    corpus_driver = local_directory_corpus_driver.LocalDirectoryCorpusDriver(
        trace_directory=kwargs.pop('_pi_data_dir'),
        url_resolver=self.app.GetURLForAbsFilename)

    # TODO(nduca): pass self.request.params to the map function [maybe].
    query_string = self.request.get('corpus_query', 'True')
    query = corpus_query.CorpusQuery.FromString(query_string)

    trace_handles = corpus_driver.GetTraceHandlesMatchingQuery(query)

    self._RunMapper(trace_handles, job_with_filenames)

  # TODO(eakuefner): Rename this and other things that assume we only have map
  def _RunMapper(self, trace_handles, job):
    self.response.content_type = 'application/json'
    output_formatter = json_output_formatter.JSONOutputFormatter(
        self.response.out)

    runner = map_runner.MapRunner(trace_handles, job,
                                  jobs=map_runner.AUTO_JOB_COUNT,
                                  output_formatters=[output_formatter])
    runner.Run()


class RunDownloadHandler(webapp2.RequestHandler):

  def post(self, *args, **kwargs):  # pylint: disable=unused-argument
    self.response.content_type = 'application/json'

    url = self.request.get('url', 'True')

    # Doesn't need to be downloaded since it's not a cloud file, just return
    # true and the path to the file.
    if not 'gs://' in url:
      self.response.write(json.dumps({'success': True, 'file': url}))
      return

    output_name = os.path.join(kwargs.pop('_pi_data_dir'), url.split('/')[-1])

    try:
      print 'Downloading: %s' % url
      cloud_storage.Copy(url, output_name)
    except cloud_storage.CloudStorageError:
      print ' -> Failed to download: %s' % url
      self.response.write(json.dumps({'success': False}))
      return

    output_name = os.path.join('/perf_insights/test_data', url.split('/')[-1])

    self.response.write(json.dumps({'success': True, 'file': output_name}))


class RunCloudMapperHandler(webapp2.RequestHandler):

  def post(self, *args, **kwargs):  # pylint: disable=unused-argument
    job_dict = json.loads(self.request.body)

    job = job_module.Job.FromDict(job_dict)

    job_with_filenames = job_module.Job(
        job.map_function_handle.ConvertHrefsToAbsFilenames(self.app))

    mapper_handle = job_with_filenames.map_function_handle
    with open(mapper_handle.modules_to_load[0].filename, 'r') as f:
      mapper = f.read()
    mapper_name = job_with_filenames.map_function_handle.function_name

    query_string = self.request.get('corpus_query', 'True')
    query = corpus_query.CorpusQuery.FromString(query_string)
    if query.max_trace_handles > MAX_TRACES:
      print 'Capping query at %d' % MAX_TRACES
      query.max_trace_handles = MAX_TRACES
    query_string = query.AsQueryString()

    params = urllib.urlencode({
        'query': query_string,
        'mapper': mapper,
        'mapper_function': mapper_name,
        'revision': 'HEAD',
        'corpus': 'https://performance-insights.appspot.com',
        'timeout': 240,
        'function_timeout': 120
        })

    cloud_mapper_url = 'https://performance-insights.appspot.com'
    if self.request.get('local') == 'true':
      cloud_mapper_url = 'http://localhost:8080'
    create_url = '%s/cloud_mapper/create' % cloud_mapper_url

    response = urllib2.urlopen(create_url, data=params)

    response_data = response.read()
    print response_data
    results = json.loads(response_data)
    if results['status']:
      jobid = results['jobid']

      status_url = '%s/cloud_mapper/status?jobid=%s' % (cloud_mapper_url, jobid)
      start_time = datetime.datetime.now()
      while datetime.datetime.now() - start_time < datetime.timedelta(
          seconds=300):
        time.sleep(1)
        print 'Waiting for results.'
        response = urllib2.urlopen(status_url)
        results = json.loads(response.read())
        if results['status'] == 'COMPLETE':
          print 'Mapping complete. Downloading results.'
          output_handle, output_name = tempfile.mkstemp()

          try:
            print '  -> %s' % results['data']
            cloud_storage.Copy(results['data'], output_name)
          except cloud_storage.CloudStorageError as e:
            print 'Cloud storage error: %s' % str(e)
            return

          map_results = ''
          with open(output_name, 'r') as f:
            map_results = f.read()
          os.close(output_handle)
          self.response.write(map_results)
          total_time = datetime.datetime.now() - start_time
          print 'Time taken: %ss' % total_time.total_seconds()
          print map_results[:128]
          return

class PerfInsightsDevServerConfig(object):
  def __init__(self):
    self.project = perf_insights_project.PerfInsightsProject()

  def GetName(self):
    return 'perf_insights'

  def GetRunUnitTestsUrl(self):
    return '/perf_insights/tests.html'

  def AddOptionstToArgParseGroup(self, g):
    g.add_argument('--pi-data-dir',
                   default=self.project.perf_insights_test_data_path)

  def GetRoutes(self, args):  # pylint: disable=unused-argument
    return [
      Route('/perf_insights/tests', TestListHandler),
      Route('/perf_insights_examples/run_map_function',
            RunMapFunctionHandler,
            defaults={
              '_pi_data_dir':
                  os.path.abspath(os.path.expanduser(args.pi_data_dir))
            }),
      Route('/perf_insights_examples/run_cloud_mapper',
            RunCloudMapperHandler,
            defaults={
              '_pi_data_dir':
                  os.path.abspath(os.path.expanduser(args.pi_data_dir))
            }),
      Route('/perf_insights_examples/download',
            RunDownloadHandler,
            defaults={
              '_pi_data_dir':
                  os.path.abspath(os.path.expanduser(args.pi_data_dir))
            })
    ]

  def GetSourcePaths(self, args):  # pylint: disable=unused-argument
    return list(self.project.source_paths)

  def GetTestDataPaths(self, args):  # pylint: disable=unused-argument
    return [('/perf_insights/test_data/',
             os.path.abspath(os.path.expanduser(args.pi_data_dir)))]
