# 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 argparse
import json
import os
import sys

tracing_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                            '..', '..'))
if tracing_path not in sys.path:
  sys.path.append(tracing_path)

from tracing import tracing_project

from paste import httpserver
from paste import fileapp

import webapp2
from webapp2 import Route, RedirectHandler

def _GetFilesIn(basedir):
  data_files = []
  for dirpath, dirnames, filenames in os.walk(basedir, followlinks=True):
    new_dirnames = [d for d in dirnames if not d.startswith('.')]
    del dirnames[:]
    dirnames += new_dirnames

    for f in filenames:
      if f.startswith('.'):
        continue
      if f == 'README.md':
        continue
      full_f = os.path.join(dirpath, f)
      rel_f = os.path.relpath(full_f, basedir)
      data_files.append(rel_f)

  data_files.sort()
  return data_files


class TestListHandler(webapp2.RequestHandler):
  def get(self, *args, **kwargs):
    test_module_resources = self.app.project.FindAllTestModuleResources()

    test_relpaths = [x.unix_style_relative_path
                     for x in test_module_resources]

    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 TestResultHandler(webapp2.RequestHandler):
  def post(self, *args, **kwargs):
    msg = self.request.body
    ostream = sys.stdout if 'PASSED' in msg else sys.stderr
    ostream.write(msg + '\n')
    return self.response.write('')


class TestsCompletedHandler(webapp2.RequestHandler):
  def post(self, *args, **kwargs):
    msg = self.request.body
    sys.stdout.write(msg + '\n')
    exit_code=(0 if 'ALL_PASSED' in msg else 1)
    if hasattr(self.app.server, 'please_exit'):
      self.app.server.please_exit(exit_code)
    return self.response.write('')


class DirectoryListingHandler(webapp2.RequestHandler):
  def get(self, *args, **kwargs):
    source_path = kwargs.pop('_source_path', None)
    mapped_path = kwargs.pop('_mapped_path', None)
    assert mapped_path.endswith('/')

    data_files_relative_to_top = _GetFilesIn(source_path)
    data_files = [mapped_path + x
                  for x in data_files_relative_to_top]

    files_as_json = json.dumps(data_files)
    self.response.content_type = 'application/json'
    return self.response.write(files_as_json)

class FileAppWithGZipHandling(fileapp.FileApp):
  def guess_type(self):
    content_type, content_encoding = \
        super(FileAppWithGZipHandling, self).guess_type()
    if not self.filename.endswith('.gz'):
      return content_type, content_encoding
    # By default, FileApp serves gzip files as their underlying type with
    # Content-Encoding of gzip. That causes them to show up on the client
    # decompressed. That ends up being surprising to our xhr.html system.
    return None, None

class SourcePathsHandler(webapp2.RequestHandler):
  def get(self, *args, **kwargs):
    source_paths = kwargs.pop('_source_paths', [])

    path = self.request.path
    # This is how we do it. Its... strange, but its what we've done since
    # the dawn of time. Aka 4 years ago, lol.
    for mapped_path in source_paths:
      rel = os.path.relpath(path, '/')
      candidate = os.path.join(mapped_path, rel)
      if os.path.exists(candidate):
        app = FileAppWithGZipHandling(candidate)
        app.cache_control(no_cache=True)
        return app
    self.abort(404)


class SimpleDirectoryHandler(webapp2.RequestHandler):
  def get(self, *args, **kwargs):
    top_path = os.path.abspath(kwargs.pop('_top_path', None))
    if not top_path.endswith(os.path.sep):
      top_path += os.path.sep

    joined_path = os.path.abspath(
        os.path.join(top_path, kwargs.pop('rest_of_path')))
    if not joined_path.startswith(top_path):
      self.response.set_status(403)
      return
    app = FileAppWithGZipHandling(joined_path)
    app.cache_control(no_cache=True)
    return app


def CreateApp(project=None,