#!/usr/bin/env python
#
# Copyright 2019 Google LLC
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


import difflib
import os
import re
import subprocess
import sys


# Any files in Git which match these patterns will be included, either directly
# or indirectly via a parent dir.
PATH_PATTERNS = [
  r'.*\.c$',
  r'.*\.cc$',
  r'.*\.cpp$',
  r'.*\.gn$',
  r'.*\.gni$',
  r'.*\.h$',
  r'.*\.storyboard$',
]

# These paths are always added to the inclusion list. Note that they may not
# appear in the isolate if they are included indirectly via a parent dir.
EXPLICIT_PATHS = [
  '../.gclient',
  '.clang-format',
  '.clang-tidy',
  'bin/fetch-clang-format',
  'bin/fetch-gn',
  'buildtools',
  'infra/bots/assets/android_ndk_darwin/VERSION',
  'infra/bots/assets/android_ndk_linux/VERSION',
  'infra/bots/assets/android_ndk_windows/VERSION',
  'infra/bots/assets/cast_toolchain/VERSION',
  'infra/bots/assets/clang_linux/VERSION',
  'infra/bots/assets/clang_win/VERSION',
  'infra/canvaskit',
  'infra/pathkit',
  'resources',
  'third_party/externals',
]

# If a parent path contains more than this many immediate child paths (ie. files
# and dirs which are directly inside it as opposed to indirect descendants), we
# will include the parent in the isolate file instead of the children. This
# results in a simpler isolate file which should need to be changed less often.
COMBINE_PATHS_THRESHOLD = 3

# Template for the isolate file content.
ISOLATE_TMPL = '''{
  'includes': [
    'run_recipe.isolate',
  ],
  'variables': {
    'files': [
%s
    ],
  },
}
'''

# Absolute path to the infra/bots dir.
INFRABOTS_DIR = os.path.realpath(os.path.dirname(os.path.abspath(__file__)))

# Absolute path to the compile.isolate file.
ISOLATE_FILE = os.path.join(INFRABOTS_DIR, 'compile.isolate')


def all_paths():
  """Return all paths which are checked in to git."""
  repo_root = os.path.abspath(os.path.join(INFRABOTS_DIR, os.pardir, os.pardir))
  output = subprocess.check_output(['git', 'ls-files'], cwd=repo_root).rstrip()
  return output.splitlines()


def get_relevant_paths():
  """Return all checked-in paths in PATH_PATTERNS or EXPLICIT_PATHS."""
  paths = []
  for f in all_paths():
    for regexp in PATH_PATTERNS:
      if re.match(regexp, f):
        paths.append(f)
        break

  paths.extend(EXPLICIT_PATHS)
  return paths


class Tree(object):
  """Tree helps with deduplicating and collapsing paths."""
  class Node(object):
    """Node represents an individual node in a Tree."""
    def __init__(self, name):
      self._children = {}
      self._name = name
      self._is_leaf = False

    @property
    def is_root(self):
      """Return True iff this is the root node."""
      return self._name is None

    def add(self, entry):
      """Add the given entry (given as a list of strings) to the Node."""
      # Remove the first element if we're not the root node.
      if not self.is_root:
        if entry[0] != self._name:
          raise ValueError('Cannot add a non-matching entry to a Node!')
        entry = entry[1:]

        # If the entry is now empty, this node is a leaf.
        if not entry:
          self._is_leaf = True
          return

      # Add a child node.
      if not self._is_leaf:
        child = self._children.get(entry[0])
        if not child:
          child = Tree.Node(entry[0])
          self._children[entry[0]] = child
        child.add(entry)

        # If we have more than COMBINE_PATHS_THRESHOLD immediate children,
        # combine them into this node.
        immediate_children = 0
        for child in self._children.itervalues():
          if child._is_leaf:
            immediate_children += 1
        if not self.is_root and immediate_children >= COMBINE_PATHS_THRESHOLD:
          self._is_leaf = True
          self._children = {}

    def entries(self):
      """Return the entries represented by this node and its children.

      Will not return children in the following cases:
        - This Node is a leaf, ie. it represents an entry which was explicitly
          inserted into the Tree, as opposed to only part of a path to other
          entries.
        - This Node has immediate children exceeding COMBINE_PATHS_THRESHOLD and
          thus has been upgraded to a leaf node.
      """
      if self._is_leaf:
        return [self._name]
      rv = []
      for child in self._children.itervalues():
        for entry in child.entries():
          if not self.is_root:
            entry = self._name + '/' + entry
          rv.append(entry)
      return rv

  def __init__(self):
    self._root = Tree.Node(None)

  def add(self, entry):
    """Add the given entry to the tree."""
    split = entry.split('/')
    if split[-1] == '':
      split = split[:-1]
    self._root.add(split)

  def entries(self):
    """Return the list of entries in the tree.

    Entries will be de-duplicated as follows:
      - Any entry which is a sub-path of another entry will not be returned.
      - Any entry which was not explicitly inserted but has children exceeding
        the COMBINE_PATHS_THRESHOLD will be returned while its children will not
        be returned.
    """
    return self._root.entries()


def relpath(repo_path):
  """Return a relative path to the given path within the repo.

  The path is relative to the infra/bots dir, where the compile.isolate file
  lives.
  """
  repo_path = '../../' + repo_path
  repo_path = repo_path.replace('../../infra/', '../')
  repo_path = repo_path.replace('../bots/', '')
  return repo_path


def get_isolate_content(paths):
  """Construct the new content of the isolate file based on the given paths."""
  lines = ['      \'%s\',' % relpath(p) for p in paths]
  lines.sort()
  return ISOLATE_TMPL % '\n'.join(lines)


def main():
  """Regenerate the compile.isolate file, or verify that it hasn't changed."""
  testing = False
  if len(sys.argv) == 2 and sys.argv[1] == 'test':
    testing = True
  elif len(sys.argv) != 1:
    print >> sys.stderr, 'Usage: %s [test]' % sys.argv[0]
    sys.exit(1)

  tree = Tree()
  for p in get_relevant_paths():
    tree.add(p)
  content = get_isolate_content(tree.entries())

  if testing:
    with open(ISOLATE_FILE, 'rb') as f:
      expect_content = f.read()
    if content != expect_content:
      print >> sys.stderr, 'Found diff in %s:' % ISOLATE_FILE
      a = expect_content.splitlines()
      b = content.splitlines()
      diff = difflib.context_diff(a, b, lineterm='')
      for line in diff:
        sys.stderr.write(line + '\n')
      print >> sys.stderr, 'You may need to run:\n\n\tpython %s' % sys.argv[0]
      sys.exit(1)
  else:
    with open(ISOLATE_FILE, 'wb') as f:
      f.write(content)


if __name__ == '__main__':
  main()
