#!/usr/bin/env python

# Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.

"""
This tool tries to fix (some) errors reported by `gn gen --check` or
`gn check`.
It will run `mb gen` in a temporary directory and it is really useful to
check for different configurations.

Usage:
    $ python tools-webrtc/gn_check_autofix.py -m some_mater -b some_bot
    or
    $ python tools-webrtc/gn_check_autofix.py -c some_mb_config
"""

import os
import re
import shutil
import subprocess
import sys
import tempfile

from collections import defaultdict

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))

TARGET_RE = re.compile(
    r'(?P<indentation_level>\s*)\w*\("(?P<target_name>\w*)"\) {$')

class TemporaryDirectory(object):
  def __init__(self):
    self._closed = False
    self._name = None
    self._name = tempfile.mkdtemp()

  def __enter__(self):
    return self._name

  def __exit__(self, exc, value, tb):
    if self._name and not self._closed:
      shutil.rmtree(self._name)
      self._closed = True


def Run(cmd):
  print 'Running:', ' '.join(cmd)
  sub = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  return sub.communicate()

def FixErrors(filename, missing_deps, deleted_sources):
  with open(filename) as f:
    lines = f.readlines()

  fixed_file = ''
  indentation_level = None
  for line in lines:
    match = TARGET_RE.match(line)
    if match:
      target = match.group('target_name')
      if target in missing_deps:
        indentation_level = match.group('indentation_level')
    elif indentation_level is not None:
      match = re.match(indentation_level + '}$', line)
      if match:
        line = ('deps = [\n' +
                ''.join('  "' + dep + '",\n' for dep in missing_deps[target]) +
                ']\n') + line
        indentation_level = None
      elif line.strip().startswith('deps'):
        is_empty_deps = line.strip() == 'deps = []'
        line = 'deps = [\n' if is_empty_deps else line
        line += ''.join('  "' + dep + '",\n' for dep in missing_deps[target])
        line += ']\n' if is_empty_deps else ''
        indentation_level = None

    if line.strip() not in deleted_sources:
      fixed_file += line

  with open(filename, 'w') as f:
    f.write(fixed_file)

  Run(['gn', 'format', filename])

def Rebase(base_path, dependency_path, dependency):
  base_path = base_path.split(os.path.sep)
  dependency_path = dependency_path.split(os.path.sep)

  first_difference = None
  shortest_length = min(len(dependency_path), len(base_path))
  for i in range(shortest_length):
    if dependency_path[i] != base_path[i]:
      first_difference = i
      break

  first_difference = first_difference or shortest_length
  base_path = base_path[first_difference:]
  dependency_path = dependency_path[first_difference:]
  return (os.path.sep.join((['..'] * len(base_path)) + dependency_path) +
          ':' + dependency)

def main():
  deleted_sources = set()
  errors_by_file = defaultdict(lambda: defaultdict(set))

  with TemporaryDirectory() as tmp_dir:
    mb_script_path = os.path.join(SCRIPT_DIR, 'mb', 'mb.py')
    mb_config_file_path = os.path.join(SCRIPT_DIR, 'mb', 'mb_config.pyl')
    mb_gen_command = ([
        mb_script_path, 'gen',
        tmp_dir,
        '--config-file', mb_config_file_path,
    ] + sys.argv[1:])

  mb_output = Run(mb_gen_command)
  errors = mb_output[0].split('ERROR')[1:]

  if mb_output[1]:
    print mb_output[1]
    return 1

  for error in errors:
    error = error.splitlines()
    target_msg = 'The target:'
    if target_msg not in error:
      target_msg = 'It is not in any dependency of'
    if target_msg not in error:
      print '\n'.join(error)
      continue
    index = error.index(target_msg) + 1
    path, target = error[index].strip().split(':')
    if error[index+1] in ('is including a file from the target:',
                          'The include file is in the target(s):'):
      dep = error[index+2].strip()
      dep_path, dep = dep.split(':')
      dep = Rebase(path, dep_path, dep)
      path = os.path.join(path[2:], 'BUILD.gn')
      errors_by_file[path][target].add(dep)
    elif error[index+1] == 'has a source file:':
      deleted_file = '"' + os.path.basename(error[index+2].strip()) + '",'
      deleted_sources.add(deleted_file)
    else:
      print '\n'.join(error)
      continue

  for path, missing_deps in errors_by_file.items():
    FixErrors(path, missing_deps, deleted_sources)

  return 0

if __name__ == '__main__':
  sys.exit(main())
