# Copyright (c) 2014 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 sys
import os
import re


def _AddToPathIfNeeded(path):
  if path not in sys.path:
    sys.path.insert(0, path)


def UpdateSysPathIfNeeded():
  p = TracingProject()
  _AddToPathIfNeeded(p.catapult_path)
  _AddToPathIfNeeded(p.py_vulcanize_path)
  _AddToPathIfNeeded(p.vinn_path)

  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'WebOb'))
  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'Paste'))
  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'six'))
  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'webapp2'))


def _FindAllFilesRecursive(source_paths):
  assert isinstance(source_paths, list)
  all_filenames = set()
  for source_path in source_paths:
    for dirpath, _, filenames in os.walk(source_path):
      for f in filenames:
        if f.startswith('.'):
          continue
        x = os.path.abspath(os.path.join(dirpath, f))
        all_filenames.add(x)
  return all_filenames

def _IsFilenameATest(x):
  if x.endswith('_test.js'):
    return True

  if x.endswith('_test.html'):
    return True

  if x.endswith('_unittest.js'):
    return True

  if x.endswith('_unittest.html'):
    return True

  # TODO(nduca): Add content test?
  return False


class TracingProject(object):
  catapult_path = os.path.abspath(
      os.path.join(os.path.dirname(__file__), os.path.pardir))

  tracing_root_path = os.path.join(catapult_path, 'tracing')
  tracing_src_path = os.path.join(tracing_root_path, 'tracing')
  extras_path = os.path.join(tracing_src_path, 'extras')
  ui_extras_path = os.path.join(tracing_src_path, 'ui', 'extras')

  catapult_third_party_path = os.path.join(catapult_path, 'third_party')

  tracing_third_party_path = os.path.join(tracing_root_path, 'third_party')
  py_vulcanize_path = os.path.join(catapult_third_party_path, 'py_vulcanize')
  vinn_path = os.path.join(catapult_third_party_path, 'vinn')

  jszip_path = os.path.join(tracing_third_party_path, 'jszip')

  glmatrix_path = os.path.join(
      tracing_third_party_path, 'gl-matrix', 'dist')

  ui_path = os.path.join(tracing_src_path, 'ui')
  d3_path = os.path.join(tracing_third_party_path, 'd3')
  chai_path = os.path.join(tracing_third_party_path, 'chai')
  mocha_path = os.path.join(tracing_third_party_path, 'mocha')

  mre_path = os.path.join(catapult_path, 'perf_insights')

  value_ui_path = os.path.join(tracing_src_path, 'value', 'ui')
  metrics_ui_path = os.path.join(tracing_src_path, 'metrics', 'ui')

  test_data_path = os.path.join(tracing_root_path, 'test_data')
  skp_data_path = os.path.join(tracing_root_path, 'skp_data')

  rjsmin_path = os.path.join(
      tracing_third_party_path, 'tvcm', 'third_party', 'rjsmin')
  rcssmin_path = os.path.join(
      tracing_third_party_path, 'tvcm', 'third_party', 'rcssmin')

  def __init__(self):
    self.source_paths = []
    self.source_paths.append(self.tracing_root_path)
    self.source_paths.append(self.tracing_third_party_path)
    self.source_paths.append(self.mre_path)
    self.source_paths.append(self.jszip_path)
    self.source_paths.append(self.glmatrix_path)
    self.source_paths.append(self.d3_path)
    self.source_paths.append(self.chai_path)
    self.source_paths.append(self.mocha_path)

  def CreateVulcanizer(self):
    from py_vulcanize import project as project_module
    return project_module.Project(self.source_paths)

  def IsD8CompatibleFile(self, filename):
    if filename.startswith(self.ui_path):
      return False

    if filename.startswith(self.value_ui_path):
      return False

    if filename.startswith(self.metrics_ui_path):
      return False

    return True

  def FindAllTestModuleRelPaths(self, pred=None):
    if pred is None:
      pred = lambda x: True

    all_filenames = _FindAllFilesRecursive([self.tracing_src_path])
    test_module_filenames = [x for x in all_filenames if
                             _IsFilenameATest(x) and pred(x)]
    test_module_filenames.sort()

    return [os.path.relpath(x, self.tracing_root_path)
            for x in test_module_filenames]

  def FindAllD8TestModuleRelPaths(self):
    return self.FindAllTestModuleRelPaths(pred=self.IsD8CompatibleFile)

  def GetConfigNames(self):
    config_files = [
        os.path.join(self.ui_extras_path, x)
        for x in os.listdir(self.ui_extras_path)
        if x.endswith('_config.html')
    ]

    config_files = [x for x in config_files if os.path.isfile(x)]

    config_basenames = [os.path.basename(x) for x in config_files]
    config_names = [re.match('(.+)_config.html$', x).group(1)
                    for x in config_basenames]
    return config_names

  def GetDefaultConfigName(self):
    assert 'full' in self.GetConfigNames()
    return 'full'

  def AddConfigNameOptionToParser(self, parser):
    choices = self.GetConfigNames()
    parser.add_argument(
        '--config', dest='config_name',
        choices=choices, default=self.GetDefaultConfigName(),
        help='Picks a browser config. Valid choices: %s' % ', '.join(choices))
    return choices

  def GetModuleNameForConfigName(self, config_name):
    return 'tracing.ui.extras.%s_config' % config_name

