#!/usr/bin/env python3
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Updates .filelist files using data from corresponding .globlist files (or
checks whether they are up to date).

bundle_data targets require an explicit source list, but maintaining these large
lists can be cumbersome. This script aims to simplify the process of updating
these lists by either expanding globs to update file lists or check that an
existing file list matches such an expansion (i.e., checking during presubmit).

The .globlist file contains a list of globs that will be expanded to either
compare or replace a corresponding .filelist. It is possible to exclude items
from the file list with globs as well. These lines are prefixed with '-' and are
processed in order, so be sure that exclusions succeed inclusions in the list of
globs. Comments and empty lines are permitted in .globfiles; comments are
prefixed with '#'.

By convention, the base name of the .globlist and .filelist files matches the
label of their corresponding bundle_data from the .gn file. In order to ensure
that these filelists don't get stale, there should also be a PRESUBMIT.py
which uses this script to check that list is up to date.

By default, the script will update the file list to match the expanded globs.
"""

import argparse
import datetime
import difflib
import glob
import os.path
import re
import subprocess
import sys

# Character to set colors in terminal. Taken, along with the printing routine
# below, from update_deps.py.
TERMINAL_ERROR_COLOR = '\033[91m'
TERMINAL_RESET_COLOR = '\033[0m'

_HEADER = """# Copyright %d The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# NOTE: this file is generated by build/ios/update_bundle_filelist.py
#       If it requires updating, you should get a presubmit error with
#       instructions on how to regenerate. Otherwise, do not edit.
""" % (datetime.datetime.now().year)

_HEADER_PATTERN = re.compile(r"""# Copyright [0-9]+ The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# NOTE: this file is generated by build/ios/update_bundle_filelist.py
#       If it requires updating, you should get a presubmit error with
#       instructions on how to regenerate. Otherwise, do not edit.
""")

_HEADER_HEIGHT = 6

_START_IGNORE_EXPANSIONS_OUTSIDE_GLOBLIST_DIR = '# push(ignore-relative)'
_STOP_IGNORE_EXPANSIONS_OUTSIDE_GLOBLIST_DIR = '# pop(ignore-relative)'


def parse_filelist(filelist_name):
  try:
    with open(filelist_name) as filelist:
      unfiltered = [l for l in filelist]
      header = ''.join(unfiltered[:_HEADER_HEIGHT])
      files = sorted(l.strip() for l in unfiltered[_HEADER_HEIGHT:])
      return (files, header)
  except Exception as e:
    print_error(f'Could not read file list: {filelist_name}', f'{type(e)}: {e}')
    return []


def get_git_command_name():
  if sys.platform.startswith('win'):
    return 'git.bat'
  return 'git'


def get_tracked_files(directory, globroot, repository_root_relative, verbose):
  try:
    git_cmd = get_git_command_name()
    with subprocess.Popen([git_cmd, 'ls-files', '--error-unmatch', directory],
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          cwd=globroot) as p:
      output = p.communicate()
      if p.returncode != 0:
        if verbose:
          print_error(
              f'Could not gather a list of tracked files in {directory}',
              f'{output[1]}')
        return set()

      files = [f.decode('utf-8') for f in output[0].splitlines()]

      # Need paths to be relative to directory in order to match expansions.
      # This should happen naturally due to cwd above, but we need to take
      # special care if relative to the repository root.
      if repository_root_relative:
        files = ['//' + f for f in files]

      # Handle Windows backslashes
      files = [f.replace('\\', '/') for f in files]

      return set(files)

  except Exception as e:
    if verbose:
      print_error(f'Could not gather a list of tracked files in {directory}',
                  f'{type(e)}: {e}')
    return set()


def combine_potentially_repository_root_relative_paths(a, b):
  if b.startswith('//'):
    # If b is relative to the repository root, os.path will consider it absolute
    # and os.path.join will fail. In this case, we can simply concatenate the
    # paths.
    return (a + b, True)
  else:
    return (os.path.join(a, b), False)


def parse_and_expand_globlist(globlist_name, glob_root):
  # The following expects glob_root not to end in a trailing slash.
  if glob_root.endswith('/'):
    glob_root = glob_root[:-1]

  check_expansions_outside_globlist_dir = True
  globlist_dir = os.path.dirname(globlist_name)

  with open(globlist_name) as globlist:
    # Paths in |files| and |to_check| must use unix separators. Using a set
    # ensures no unwanted duplicates. The files in |to_check| must be in the
    # globroot or a subdirectory.
    files = set()
    to_check = set()
    for g in globlist:
      g = g.strip()

      # Ignore blank lines
      if not g:
        continue

      # Toggle error checking.
      if g == _START_IGNORE_EXPANSIONS_OUTSIDE_GLOBLIST_DIR:
        check_expansions_outside_globlist_dir = False
      elif g == _STOP_IGNORE_EXPANSIONS_OUTSIDE_GLOBLIST_DIR:
        check_expansions_outside_globlist_dir = True

      # Ignore comments.
      if not g or g.startswith('#'):
        continue

      # Exclusions are prefixed with '-'.
      is_exclusion = g.startswith('-')
      if is_exclusion:
        g = g[1:]

      (combined,
       root_relative) = combine_potentially_repository_root_relative_paths(
           glob_root, g)

      prefix_size = len(glob_root)
      if not root_relative:
        # We need to account for the separator.
        prefix_size += 1

      expansion = glob.glob(combined, recursive=True)

      # Filter out directories.
      expansion = [f for f in expansion if os.path.isfile(f)]

      if check_expansions_outside_globlist_dir:
        for f in expansion:
          relative = os.path.relpath(f, globlist_dir)
          if relative.startswith('..'):
            raise Exception(f'Globlist expansion outside globlist dir: {f}')

      # Make relative to |glob_root|.
      expansion = [f[prefix_size:] for f in expansion]

      # Handle Windows backslashes
      expansion = [f.replace('\\', '/') for f in expansion]

      # Since paths in |expansion| only use unix separators, it is safe to
      # compare for both the purpose of exclusion and addition.
      if is_exclusion:
        files = files.difference(expansion)
      else:
        files = files.union(expansion)

    # Return a sorted list.
    return sorted(files)


def compare_lists(a, b):
  differ = difflib.Differ()
  full_diff = differ.compare(a, b)
  lines = [d for d in full_diff if not d.startswith('  ')]
  additions = [l[2:] for l in lines if l.startswith('+ ')]
  removals = [l[2:] for l in lines if l.startswith('- ')]
  return (additions, removals)


def write_filelist(filelist_name, files, header):
  try:
    with open(filelist_name, 'w', encoding='utf-8', newline='') as filelist:
      if not _HEADER_PATTERN.search(header):
        header = _HEADER
      filelist.write(header)
      for file in files:
        filelist.write(f'{file}\n')
  except Exception as e:
    print_error(f'Could not write file list: {filelist_name}',
                f'{type(e)}: {e}')
    return []


def process_filelist(filelist, globlist, globroot, check=False, verbose=False):
  files_from_globlist = []
  try:
    files_from_globlist = parse_and_expand_globlist(globlist, globroot)
  except Exception as e:
    if verbose:
      print_error(f'Could not read glob list: {globlist}', f'{type(e)}: {e}')
    return 1

  (files, header) = parse_filelist(filelist)

  (additions, removals) = compare_lists(files, files_from_globlist)
  to_ignore = set()

  # Ignore additions of untracked files.
  if additions:
    directories = set([os.path.dirname(f) for f in additions])
    tracked_files = set()
    for d in directories:
      (combined,
       root_relative) = combine_potentially_repository_root_relative_paths(
           globroot, d)
      relative = os.path.relpath(combined, globroot)
      tracked_files = tracked_files.union(
          get_tracked_files(relative, globroot, root_relative, verbose))
    to_ignore = set(additions).difference(tracked_files)
    additions = [f for f in additions if f in tracked_files]

  files_from_globlist = [f for f in files_from_globlist if f not in to_ignore]

  if check:
    if not _HEADER_PATTERN.search(header):
      if verbose:
        print_error(f'Unexpected header for {filelist}', f'{header}')
      return 1
    if not additions and not removals:
      return 0
    if verbose:
      pretty_additions = ['+ ' + f for f in additions]
      pretty_removals = ['- ' + f for f in removals]
      pretty_diff = '\n'.join(pretty_additions + pretty_removals)
      print_error('File list does not match glob expansion', f'{pretty_diff}')
    return 1
  else:
    write_filelist(filelist, files_from_globlist, header)
    return 0


def main(args):
  parser = argparse.ArgumentParser(
      description=__doc__, formatter_class=argparse.RawTextHelpFormatter)
  parser.add_argument('filelist', help='Contains one file per line')
  parser.add_argument('globlist',
                      help='Contains globs that, when expanded, '
                      'should match the filelist. Use '
                      '--help for details on syntax')
  parser.add_argument('globroot',
                      help='Directory from which globs are relative')
  parser.add_argument('-c',
                      '--check',
                      action='store_true',
                      help='Prevents modifying the file list')
  parser.add_argument('-v',
                      '--verbose',
                      action='store_true',
                      help='Use this to print details on differences')
  args = parser.parse_args()
  return process_filelist(args.filelist,
                          args.globlist,
                          args.globroot,
                          check=args.check,
                          verbose=args.verbose)


def print_error(error_message, error_info):
  """ Print the `error_message` with additional `error_info` """
  color_start, color_end = adapted_color_for_output(TERMINAL_ERROR_COLOR,
                                                    TERMINAL_RESET_COLOR)

  error_message = color_start + 'ERROR: ' + error_message + color_end
  if len(error_info) > 0:
    error_message = error_message + '\n' + error_info
  print(error_message, file=sys.stderr)


def adapted_color_for_output(color_start, color_end):
  """ Returns a the `color_start`, `color_end` tuple if the output is a
    terminal, or empty strings otherwise """
  if not sys.stdout.isatty():
    return '', ''
  return color_start, color_end


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
