#!/usr/bin/env python3
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Linter for various README.md files."""

import difflib
import logging
import os
import re
import sys

TOP_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))

# Find chromite!
sys.path.insert(0, os.path.join(TOP_DIR, '..', '..'))

from chromite.lib import commandline
from chromite.lib import git
from chromite.lib import osutils


def GetActiveProjects():
  """Return the list of active projects."""
  # Look at all the paths (files & dirs) in the top of the git repo.  This way
  # we ignore local directories devs created that aren't actually committed.
  cmd = ['ls-tree', '--name-only', '-z', 'HEAD']
  result = git.RunGit(TOP_DIR, cmd)

  # Split the output on NULs to avoid whitespace/etc... issues.
  paths = result.stdout.split('\0')

  # ls-tree -z will include a trailing NUL on all entries, not just seperation,
  # so filter it out if found (in case ls-tree behavior changes on us).
  for path in [x for x in paths if x]:
    if os.path.isdir(os.path.join(TOP_DIR, path)):
      yield path


def CheckTopLevel():
  """Check the top level README.md list."""
  ret = 0
  path = os.path.join(TOP_DIR, 'README.md')
  data = osutils.ReadFile(path).splitlines()

  # Look for the directory header.
  try:
    i = data.index('# Local Project Directory')
  except ValueError:
    logging.error('README.md index out of sync')
    return 1
  data = data[i + 1:]

  # Pull out all the linked projects.
  listed_projs = []
  listed_dirs = []
  for line in data:
    # Break once we hit the end of the table.
    if line.startswith('#'):
      break

    m = re.match(r'^[|] \[([^]]+)*\]\(\./([^)]*)/\)', line)
    if m:
      listed_projs.append(m.group(1))
      listed_dirs.append(m.group(2))
  logging.debug('README.md projects: %s', listed_projs)

  sorted_projs = sorted(listed_projs)
  if listed_projs != sorted_projs:
    ret = 1
    lines = list(difflib.unified_diff(listed_projs, sorted_projs, lineterm=''))
    logging.error('README.md project listing should be kept sorted:\n%s',
                  '\n'.join(lines[2:]))

  # Check the list in README.md for outdated entries.
  old_dirs = []
  for project_dir in listed_dirs:
    path = os.path.join(TOP_DIR, project_dir)
    if not os.path.isdir(path):
      old_dirs.append(path)
  if old_dirs:
    ret = 1
    logging.error('README.md: found stale project entries: %s', old_dirs)

  # Check the local source repo for missing entries.
  existing_projs = sorted(GetActiveProjects())
  logging.debug('Found active projects: %s', existing_projs)
  new_projs = []
  for proj in existing_projs:
    path = os.path.join(TOP_DIR, proj)
    if os.path.isdir(path) and proj not in listed_projs:
      new_projs.append(proj)
  if new_projs:
    ret = 1
    logging.error('README.md: document new projects: %s', new_projs)

  return ret


def CheckSubdirs():
  """Check the subdir README.md files exist."""
  # Legacy projects that don't have a README.md file.
  # Someone should write some docs :D.
  LEGACYLIST = (
      'attestation',
      'avtest_label_detect',
      'buffet',
      'cros-disks',
      'fitpicker',
      'image-burner',
      'init',
      'libchromeos-ui',
      'libcontainer',
      'modem-utilities',
      'mtpd',
      'salsa',
      'thd',
      'timberslide',
      'tpm_manager',
      'trim',
      'userfeedback',
      'userspace_touchpad',
      'vpn-manager',
  )

  ret = 0
  for proj in GetActiveProjects():
    readme = os.path.join(TOP_DIR, proj, 'README.md')
    if os.path.exists(readme):
      if proj in LEGACYLIST:
        logging.error(
            '*** Project "%s" is in no-README LEGACYLIST, but actually has '
            'one. Please remove it from LEGACYLIST!', proj)
    else:
      if not proj in LEGACYLIST:
        logging.error('*** Project "%s" needs a README.md file', proj)
        ret = 1
  return ret


def GetParser():
  """Return an argument parser."""
  parser = commandline.ArgumentParser(description=__doc__)
  parser.add_argument('--extensions', default='gyp,gypi',
                      help='Comma delimited file extensions to check. '
                           '(default: %(default)s)')
  parser.add_argument('files', nargs='*',
                      help='Files to run lint.')
  return parser


def main(argv):
  parser = GetParser()
  opts = parser.parse_args(argv)
  opts.Freeze()

  return CheckTopLevel() | CheckSubdirs()


if __name__ == '__main__':
  commandline.ScriptWrapperMain(lambda _: main)
