#!/usr/bin/env python3

# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Finds files to lint amongst all of Cobalt's files."""

import sys
import os
# Ensure that this file can import from cobalt root even if run as a script.
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import subprocess
import re

try:
  from subprocess import DEVNULL  # py3k
except ImportError:
  DEVNULL = open(os.devnull, 'wb')

THIS_DIR = os.path.dirname(__file__)
SRC_ROOT_DIR = os.path.abspath(os.path.join(THIS_DIR, os.pardir))

# A list of directories which should be skipped while walking the directory
# tree looking for C++ files to be linted. We also skip directories starting
# with a "." such as ".git"
SKIP_LINT_DIRS = [
    os.path.join(SRC_ROOT_DIR, 'out'),
    os.path.join(SRC_ROOT_DIR, 'sysroot'),
    os.path.join(SRC_ROOT_DIR, 'third_party'),
    os.path.join(SRC_ROOT_DIR, 'build'),
    os.path.join(SRC_ROOT_DIR, 'cmake-build-debug'),
    os.path.join(SRC_ROOT_DIR, 'src', 'bin', 'config_parser', 'src',
                 'source_generator', 'source_generator_test_files'),
]


# In version 3.6 and newer, the subprocess.check_output() function needs to be
# passed an encoding type to return a string, otherwise it returns a bytes type.
def _run_command(*command):
  if sys.version_info >= (3, 6):
    return subprocess.check_output(command, stderr=DEVNULL, encoding='UTF-8')
  else:
    return subprocess.check_output(command, stderr=DEVNULL)


# Given a directory's parent path and name, returns a boolean indicating whether
# or not the directory should be skipped for linting.
def _should_skip_dir(parent_path, name):
  if name.startswith('.'):
    return True
  full_path = os.path.join(parent_path, name)
  for p in SKIP_LINT_DIRS:
    if full_path.startswith(p):
      return True
  return False


# Find the newest parent commit in the upstream branch (or HEAD if no such
# commit is found).
def _get_diff_base():
  try:
    upstream = _run_command('git', 'rev-parse', '--abbrev-ref',
                            '--symbolic-full-name', '"@{u}"').strip()
  except subprocess.CalledProcessError:
    upstream = 'origin/master'
  local_commit = _run_command('git', 'rev-list', 'HEAD',
                              '^' + upstream).strip().split('\n')[-1]
  if not local_commit:
    return 'HEAD'
  return _run_command('git', 'rev-parse', local_commit + '^').strip()


# Get the source files that have been modified in this branch. By default this
# uses `git diff` against the newest parent commit in the upstream branch (or
# against HEAD if no such commit is found).
def _get_git_files():
  diff_base = _get_diff_base()
  return _run_command('git', 'diff', '--name-only',
                      diff_base).strip().split('\n')


def files_to_lint(extensions, only_directories=[], all_files=False):
  files_to_lint = []
  only_directories = [os.path.join(SRC_ROOT_DIR, d) for d in only_directories]
  git_files = []
  if not all_files:
    git_files = [os.path.join(SRC_ROOT_DIR, f) for f in _get_git_files()]

  for root, dirs, files in os.walk(SRC_ROOT_DIR):
    for f in files:
      if f.endswith(extensions):
        full_path = os.path.join(root, f)

        if only_directories and len(
            [d for d in only_directories if full_path.startswith(d)]) == 0:
          continue

        if not all_files and full_path not in git_files:
          continue

        files_to_lint.append(full_path)

    # Before recursing into directories remove the ones we want to skip.
    dirs_to_skip = [dir for dir in dirs if _should_skip_dir(root, dir)]
    for d in dirs_to_skip:
      dirs.remove(d)

  return files_to_lint
