#!/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 os
import shutil
from distutils.version import LooseVersion

import utils

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)
  shutil.move(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
