#!/usr/bin/env python

# 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.

import argparse
import json
import os.path
import subprocess
import sys

fuchsia_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
sys.path.append(os.path.join(fuchsia_root, 'src'))

from area_dependency_exceptions import exceptions

allowed_deps = [
    # These dependencies are always allowed:
    # https://fuchsia.googlesource.com/fuchsia/+/refs/heads/master/docs/development/source_code/layout.md#dependency-structure
    '//build',
    '//buildtools',
    '//sdk',
    '//third_party',

    # The follow entries are temporarily allowed universally, but should be
    # moved to //sdk or //src/lib:
    # Code libraries
    '//garnet/public/lib',
    '//garnet/public/rust',
    '//zircon/public/lib',
    '//zircon/public/fidl',
    '//zircon/public/banjo',
    '//zircon/system/public',

    # Tools
    '//garnet/go/src/pm:pm_bin(//build/toolchain:host_x64)',
    '//garnet/bin/cmc:cmc(//build/toolchain:host_x64)',
    '//zircon/public/tool',
    '//garnet/go/src/fidl:fidlgen(//build/toolchain:host_x64)',
    '//garnet/go/src/fidl:fidlgen_llcpp(//build/toolchain:host_x64)',
    '//garnet/go/src/fidlmerge:fidlmerge(//build/toolchain:host_x64)',

    # This is currently implicitly generated as a dependency on any C++
    # generation of a FIDL target.
    # TODO(ctiller): File an issue for cleaning this up.
    '//src/connectivity/overnet/lib/protocol:fidl_stream',
]

target_types_to_check = [
    'action',
    'executable',
    'loadable_module',
    'shared_library',
    'source_set',
    'static_library',
]


class DisallowedDepsRecord:
    def __init__(self):
        self.count = 0
        self.labels = {}

    def AddBadDep(self, label, dep):
        self.count = self.count + 1
        if label not in self.labels:
            self.labels[label] = []
        self.labels[label].append(dep)


# An area is defined as a directory within //src/ that contains an OWNERS file.
# See docs/development/source_code/layout.md
def area_for_label(source_dir, label):
    src_prefix = '//src/'
    if not label.startswith(src_prefix):
        return ''  # Not in an area
    if ':' in label:
        label = label[0:label.find(':')]
    while label != '//':
        expected_owners_path = os.path.join(source_dir, label[2:], 'OWNERS')
        if os.path.exists(expected_owners_path):
            return label
        label = os.path.dirname(label)
    return ''


# Checks dependency rules as described in
# docs/development/source_code/layout.md#dependency-structure
def dep_allowed(label, label_area, dep, dep_area, ignore_exceptions):
    # Targets can depend on globally allowed targets
    for a in allowed_deps:
        if dep.startswith(a):
            return True
    # Targets within an area can depend on other targets in the same area
    if label_area == dep_area:
        return True
    # Targets can depend on '//(../*)lib'
    while label != '//':
        if dep.startswith(label + '/lib/'):
            return True
        label = os.path.dirname(label)
    if ignore_exceptions:
        return False
    # Some areas are temporarily allowed additional dependencies
    if label_area in exceptions:
        prefixes = exceptions[label_area]
        for prefix in prefixes:
            if dep.startswith(prefix):
                return True
    return False


def record_bad_dep(bad_deps, area, label, bad_dep):
    if area not in bad_deps:
        bad_deps[area] = DisallowedDepsRecord()
    bad_deps[area].AddBadDep(label, bad_dep)


def extract_build_graph(gn_binary, out_dir):
    args = [gn_binary, 'desc', out_dir, '//src/*', '--format=json',
            '--all-toolchains']
    json_build_graph = subprocess.check_output(args)
    return json.loads(json_build_graph)


def main():
    parser = argparse.ArgumentParser(
        description='Check dependency graph in areas')
    parser.add_argument('--out', default='out/default',
                        help='Build output directory')
    parser.add_argument('--ignore-exceptions', action='store_true',
                        help='Ignore registered exceptions.  ' +
                        'Set to see all dependency issues')
    args = parser.parse_args()

    gn_binary = os.path.join(fuchsia_root, 'buildtools', 'gn')
    targets = extract_build_graph(gn_binary, os.path.join(fuchsia_root,
                                                          args.out))

    disallowed_dependencies = {}
    for label, target in targets.iteritems():
        if target['type'] not in target_types_to_check:
            continue
        label_area = area_for_label(fuchsia_root, label)
        for dep in target['deps']:
            dep_area = area_for_label(fuchsia_root, dep)
            if not dep_allowed(label, label_area, dep,
                               dep_area, args.ignore_exceptions):
                record_bad_dep(disallowed_dependencies, label_area, label, dep)

    total_count = 0
    for area in sorted(disallowed_dependencies.keys()):
        disallowed_deps = disallowed_dependencies[area]
        print 'Area %s has %d disallowed dependencies:' % (
            area, disallowed_deps.count)
        total_count = total_count + disallowed_deps.count

        for label in sorted(disallowed_deps.labels.keys()):
            bad_deps = disallowed_deps.labels[label]
            print '  Target %s has %d disallowed dependencies:' % (
                label, len(bad_deps))
            for dep in sorted(bad_deps):
                print '    %s' % dep
            print
        print

    print 'Found %d dependency errors' % total_count
    if total_count != 0:
        return 1
    return 0


if __name__ == '__main__':
    sys.exit(main())
