#!/usr/bin/env python
# Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import utils

from distutils.version import LooseVersion
import os
import shutil

if utils.is_python3():
  from html.parser import HTMLParser
else:
  from HTMLParser import HTMLParser


def add_r8_dependency(checkout_dir, temp_dir, minified):
  build_file = os.path.join(checkout_dir, 'build.gradle')
  assert os.path.isfile(build_file), (
      'Expected a file to be present at {}'.format(build_file))

  with open(build_file) as f:
    lines = f.readlines()

  added_r8_dependency = False
  is_inside_dependencies = False

  with open(build_file, 'w') as f:
    gradle_version = None
    for line in lines:
      stripped = line.strip()
      if stripped == 'dependencies {':
        assert not is_inside_dependencies, (
            'Unexpected line with \'dependencies {\'')
        is_inside_dependencies = True
      if is_inside_dependencies:
        if '/r8.jar' in stripped or '/r8lib.jar' in stripped:
          # Skip line to avoid dependency on r8.jar
          continue
        elif 'com.android.tools.build:gradle:' in stripped:
          gradle_version = stripped[stripped.rindex(':')+1:-1]
          indent = ''.ljust(line.index('classpath'))
          jar = os.path.join(temp_dir, 'r8lib.jar' if minified else 'r8.jar')
          f.write('{}classpath files(\'{}\')\n'.format(indent, jar))
          added_r8_dependency = True
        elif stripped == '}':
          is_inside_dependencies = False
      f.write(line)

  assert added_r8_dependency, 'Unable to add R8 as a dependency'
  assert gradle_version
  assert LooseVersion(gradle_version) >= LooseVersion('3.2'), (
      'Unsupported gradle version: {} (must use at least gradle '
          + 'version 3.2)').format(gradle_version)

def add_settings_gradle(checkout_dir, name):
  settings_file = os.path.join(checkout_dir, 'settings.gradle')
  if os.path.isfile(settings_file):
    return

  with open(settings_file, "w+") as f:
    f.write("rootProject.name = '{}'\n".format(name))

def remove_r8_dependency(checkout_dir):
  build_file = os.path.join(checkout_dir, 'build.gradle')
  assert os.path.isfile(build_file), (
      'Expected a file to be present at {}'.format(build_file))
  with open(build_file) as f:
    lines = f.readlines()
  with open(build_file, 'w') as f:
    for line in lines:
      if ('/r8.jar' not in line) and ('/r8lib.jar' not in line):
        f.write(line)

def GetMinAndCompileSdk(app, checkout_dir, apk_reference):
  compile_sdk = app.compile_sdk
  min_sdk = app.min_sdk

  if not compile_sdk or not min_sdk:
    build_gradle_file = os.path.join(checkout_dir, app.module, 'build.gradle')
    assert os.path.isfile(build_gradle_file), (
        'Expected to find build.gradle file at {}'.format(build_gradle_file))

    # Attempt to find the sdk values from build.gradle.
    with open(build_gradle_file) as f:
      for line in f.readlines():
        stripped = line.strip()
        if stripped.startswith('compileSdkVersion '):
          if not app.compile_sdk:
            assert not compile_sdk
            compile_sdk = int(stripped[len('compileSdkVersion '):])
        elif stripped.startswith('minSdkVersion '):
          if not app.min_sdk:
            assert not min_sdk
            min_sdk = int(stripped[len('minSdkVersion '):])

  assert min_sdk, (
      'Expected to find `minSdkVersion` in {}'.format(build_gradle_file))
  assert compile_sdk, (
      'Expected to find `compileSdkVersion` in {}'.format(build_gradle_file))

  return (min_sdk, compile_sdk)

def IsGradleTaskName(x):
  # Check that it is non-empty.
  if not x:
    return False
  # Check that there is no whitespace.
  for c in x:
    if c.isspace():
      return False
  # Check that the first character following an optional ':' is a lower-case
  # alphabetic character.
  c = x[0]
  if c == ':' and len(x) >= 2:
    c = x[1]
  return c.isalpha() and c.islower()

def IsGradleCompilerTask(x, shrinker):
  if 'r8' in shrinker:
    assert 'transformClassesWithDexBuilderFor' not in x
    assert 'transformDexArchiveWithDexMergerFor' not in x
    return 'transformClassesAndResourcesWithR8For' in x

  assert shrinker == 'pg'
  return ('transformClassesAndResourcesWithProguard' in x
      or 'transformClassesWithDexBuilderFor' in x
      or 'transformDexArchiveWithDexMergerFor' in x)

def ListFiles(directory, predicate=None):
  files = []
  for root, directories, filenames in os.walk(directory):
    for filename in filenames:
      file = os.path.join(root, filename)
      if predicate is None or predicate(file):
        files.append(file)
  return files

def SetPrintConfigurationDirective(app, checkout_dir, destination):
  proguard_config_file = FindProguardConfigurationFile(app, checkout_dir)
  with open(proguard_config_file) as f:
    lines = f.readlines()
  with open(proguard_config_file, 'w') as f:
    for line in lines:
      if '-printconfiguration' not in line:
        f.write(line)
    # Check that there is a line-break at the end of the file or insert one.
    if len(lines) and lines[-1].strip():
      f.write('\n')
    f.write('-printconfiguration {}\n'.format(destination))

def FindProguardConfigurationFile(app, checkout_dir):
  candidates = [
      'proguard.cfg',
      'proguard-rules.pro',
      'proguard-rules.txt',
      'proguard-project.txt']
  for candidate in candidates:
    proguard_config_file = os.path.join(checkout_dir, app.module, candidate)
    if os.path.isfile(proguard_config_file):
      return proguard_config_file
  # Currently assuming that the Proguard configuration file can be found at
  # one of the predefined locations.
  assert False, 'Unable to find Proguard configuration file'

def Move(src, dst, quiet=False):
  if not quiet:
    print('Moving `{}` to `{}`'.format(src, dst))
  dst_parent = os.path.dirname(dst)
  if not os.path.isdir(dst_parent):
    os.makedirs(dst_parent)
  elif os.path.isdir(dst):
    shutil.rmtree(dst)
  elif os.path.isfile(dst):
    os.remove(dst)
  os.rename(src, dst)

def MoveDir(src, dst, quiet=False):
  assert os.path.isdir(src)
  Move(src, dst, quiet=quiet)

def MoveFile(src, dst, quiet=False):
  assert os.path.isfile(src), "Expected a file to be present at " + src
  Move(src, dst, quiet=quiet)

def MoveProfileReportTo(dest_dir, build_stdout, quiet=False):
  html_file = None
  profile_message = 'See the profiling report at: '
  # We are not interested in the profiling report for buildSrc.
  for line in build_stdout:
    if (profile_message in line) and ('buildSrc' not in line):
      assert not html_file, "Only one report should be created"
      html_file = line[len(profile_message):]
      if html_file.startswith('file://'):
        html_file = html_file[len('file://'):]

  if not html_file:
    return

  assert os.path.isfile(html_file), 'Expected to find HTML file at {}'.format(
      html_file)
  MoveFile(html_file, os.path.join(dest_dir, 'index.html'), quiet=quiet)

  html_dir = os.path.dirname(html_file)
  for dir_name in ['css', 'js']:
    MoveDir(os.path.join(html_dir, dir_name), os.path.join(dest_dir, dir_name),
        quiet=quiet)

def MoveXMLTestResultFileTo(xml_test_result_dest, test_stdout, quiet=False):
  xml_test_result_file = None
  xml_result_reporter_message = 'XML test result file generated at '
  for line in test_stdout:
    if xml_result_reporter_message in line:
      index_from = (
          line.index(xml_result_reporter_message)
              + len(xml_result_reporter_message))
      index_to = line.index('.xml') + len('.xml')
      xml_test_result_file = line[index_from:index_to]
      break

  assert os.path.isfile(xml_test_result_file), (
      'Expected to find XML file at {}'.format(xml_test_result_file))

  MoveFile(xml_test_result_file, xml_test_result_dest, quiet=quiet)

def ParseProfileReport(profile_dir):
  html_file = os.path.join(profile_dir, 'index.html')
  assert os.path.isfile(html_file)

  parser = ProfileReportParser()
  with open(html_file) as f:
    for line in f.readlines():
      parser.feed(line)
  return parser.result

# A simple HTML parser that recognizes the following pattern:
#
# <tr>
# <td class="indentPath">:app:transformClassesAndResourcesWithR8ForRelease</td>
# <td class="numeric">3.490s</td>
# <td></td>
# </tr>
class ProfileReportParser(HTMLParser):
  def __init__(self):
    HTMLParser.__init__(self)
    self.entered_table_row = False
    self.entered_task_name_cell = False
    self.entered_duration_cell = False

    self.current_task_name = None
    self.current_duration = None

    self.result = {}

  def handle_starttag(self, tag, attrs):
    entered_table_row_before = self.entered_table_row
    entered_task_name_cell_before = self.entered_task_name_cell

    self.entered_table_row = (tag == 'tr')
    self.entered_task_name_cell = (tag == 'td' and entered_table_row_before)
    self.entered_duration_cell = (
        self.current_task_name
            and tag == 'td'
            and entered_task_name_cell_before)

  def handle_endtag(self, tag):
    if tag == 'tr':
      if self.current_task_name and self.current_duration:
        self.result[self.current_task_name] = self.current_duration
      self.current_task_name = None
      self.current_duration = None
    self.entered_table_row = False

  def handle_data(self, data):
    stripped = data.strip()
    if not stripped:
      return
    if self.entered_task_name_cell:
      if IsGradleTaskName(stripped):
        self.current_task_name = stripped
    elif self.entered_duration_cell and stripped.endswith('s'):
      duration = stripped[:-1]
      if 'm' in duration:
        tmp = duration.split('m')
        minutes = int(tmp[0])
        seconds = float(tmp[1])
      else:
        minutes = 0
        seconds = float(duration)
      self.current_duration = 60 * minutes + seconds
    self.entered_table_row = False
