#!/usr/bin/env fuchsia-vendored-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 platform
import os.path
import subprocess
import sys

HOST_PLATFORM = "%s-%s" % (
    platform.system().lower().replace("darwin", "mac"),
    {
        "x86_64": "x64",
        "aarch64": "arm64",
    }[platform.machine()],
)

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/+/HEAD/docs/development/source_code/layout.md#dependency-structure
    '//build',
    '//prebuilt',
    '//sdk',
    '//third_party',

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

    # Tools
    '//tools',
    # Will move to //tools or //sdk:
    '//garnet/go/src/pm:pm_bin(//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',
    '//src/connectivity/overnet/lib/embedded:runtime',
]

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, testonly, 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/'
    # Targets marked testonly can depend on '//(../*)testing/'
    while label != '//':
        if dep.startswith(label + '/lib/'):
            return True
        if testonly and dep.startswith(label + '/testing'):
            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, 'prebuilt', 'third_party', 'gn', HOST_PLATFORM, 'gn')
    targets = extract_build_graph(
        gn_binary, os.path.join(fuchsia_root, args.out))

    disallowed_dependencies = {}
    for label, target in targets.items():
        if target['type'] not in target_types_to_check:
            continue
        label_area = area_for_label(fuchsia_root, label)
        testonly = target['testonly']
        for dep in target['deps']:
            dep_area = area_for_label(fuchsia_root, dep)
            if not dep_allowed(label, label_area, dep, dep_area, testonly,
                               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())
