#!/usr/bin/env python

# Copyright (c) 2017 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.

import argparse
import collections
import os
import re
import sys

# TARGET_RE matches a GN target, and extracts the target name and the contents.
TARGET_RE = re.compile(
    r'(?P<indent>\s*)\w+\("(?P<target_name>\w+)"\) {'
    r'(?P<target_contents>.*?)'
    r'(?P=indent)}', re.MULTILINE | re.DOTALL)

# SOURCES_RE matches a block of sources inside a GN target.
SOURCES_RE = re.compile(r'sources \+?= \[(?P<sources>.*?)\]',
                        re.MULTILINE | re.DOTALL)

ERROR_MESSAGE = ("{build_file_path} in target '{target_name}':\n"
                 "  Source file '{source_file}'\n"
                 "  crosses boundary of package '{subpackage}'.")


class PackageBoundaryViolation(
        collections.namedtuple(
            'PackageBoundaryViolation',
            'build_file_path target_name source_file subpackage')):
    def __str__(self):
        return ERROR_MESSAGE.format(**self._asdict())


def _BuildSubpackagesPattern(packages, query):
    """Returns a regular expression that matches source files inside subpackages
  of the given query."""
    query += os.path.sep
    length = len(query)
    pattern = r'\s*"(?P<source_file>(?P<subpackage>'
    pattern += '|'.join(
        re.escape(package[length:].replace(os.path.sep, '/'))
        for package in packages if package.startswith(query))
    pattern += r')/[\w\./]*)"'
    return re.compile(pattern)


def _ReadFileAndPrependLines(file_path):
    """Reads the contents of a file."""
    with open(file_path) as f:
        return "".join(f.readlines())


def _CheckBuildFile(build_file_path, packages):
    """Iterates over all the targets of the given BUILD.gn file, and verifies that
  the source files referenced by it don't belong to any of it's subpackages.
  Returns an iterator over PackageBoundaryViolations for this package.
  """
    package = os.path.dirname(build_file_path)
    subpackages_re = _BuildSubpackagesPattern(packages, package)

    build_file_contents = _ReadFileAndPrependLines(build_file_path)
    for target_match in TARGET_RE.finditer(build_file_contents):
        target_name = target_match.group('target_name')
        target_contents = target_match.group('target_contents')
        for sources_match in SOURCES_RE.finditer(target_contents):
            sources = sources_match.group('sources')
            for subpackages_match in subpackages_re.finditer(sources):
                subpackage = subpackages_match.group('subpackage')
                source_file = subpackages_match.group('source_file')
                if subpackage:
                    yield PackageBoundaryViolation(build_file_path,
                                                   target_name, source_file,
                                                   subpackage)


def CheckPackageBoundaries(root_dir, build_files=None):
    packages = [
        root for root, _, files in os.walk(root_dir) if 'BUILD.gn' in files
    ]

    if build_files is not None:
        for build_file_path in build_files:
            assert build_file_path.startswith(root_dir)
    else:
        build_files = [
            os.path.join(package, 'BUILD.gn') for package in packages
        ]

    messages = []
    for build_file_path in build_files:
        messages.extend(_CheckBuildFile(build_file_path, packages))
    return messages


def main(argv):
    parser = argparse.ArgumentParser(
        description='Script that checks package boundary violations in GN '
        'build files.')

    parser.add_argument('root_dir',
                        metavar='ROOT_DIR',
                        help='The root directory that contains all BUILD.gn '
                        'files to be processed.')
    parser.add_argument('build_files',
                        metavar='BUILD_FILE',
                        nargs='*',
                        help='A list of BUILD.gn files to be processed. If no '
                        'files are given, all BUILD.gn files under ROOT_DIR '
                        'will be processed.')
    parser.add_argument('--max_messages',
                        type=int,
                        default=None,
                        help='If set, the maximum number of violations to be '
                        'displayed.')

    args = parser.parse_args(argv)

    messages = CheckPackageBoundaries(args.root_dir, args.build_files)
    messages = messages[:args.max_messages]

    for i, message in enumerate(messages):
        if i > 0:
            print
        print message

    return bool(messages)


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