#!/usr/bin/env python3
# Copyright 2020 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.
"""Checks the visibility of all cobalt gn targets"""

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 json

# Find the root directory of the cobalt core repository (One directory up from the tools/ directory)
cobalt_root = os.path.abspath(
    os.path.join(os.path.join(os.path.dirname(__file__), '..')))
global_visibility_whitelist = ['//src/public', '//src/lib/client']

# This is the list of targets that are currently used out-of-tree.
#
# Any new targets used outside of the tree should be accessible through //src/public or //src/lib/client
#
# DO NOT ADD ANY NEW ENTRIES TO THIS DICT
out_of_tree_visibility_whitelist = {
    '//src/cobalt/bin/app:cobalt_app_unittests': [
        '//src/logger:fake_logger',
        '//src/logger:logger_test_utils',
    ],
    '//src/cobalt/bin/app:lib': [
        '//src/lib/util:file_util',
        '//src/lib/util:pem_util',
        '//src/lib/util:posix_file_system',
        '//src/logger:logger',
        '//src/system_data:configuration_data',
        '//src/system_data:system_data',
    ],
    '//src/cobalt/bin/testapp:cobalt_testapp': [
        '//src/lib/util:datetime_util',
        '//src/registry:cobalt_registry_proto',
        '//src/registry:cobalt_registry_proto_protoc_outputs',
    ],
}


def main():
  out_path = os.path.join(cobalt_root, 'out')
  p = subprocess.Popen(
      ['gn', 'desc', out_path, '//src/*', 'visibility', '--format=json'],
      stdout=subprocess.PIPE)
  out, err = p.communicate()

  if p.returncode != 0:
    print('Received non-zero return code (%s)' % p.returncode)
    print(out.decode())
    return 1

  data = json.loads(out)

  globally_visibile = []
  out_of_tree_visibility = {}

  errors = 0

  for target, attributes in data.items():
    whitelisted = False
    for whitelist in global_visibility_whitelist:
      if target.startswith(whitelist):
        whitelisted = True

    if whitelisted:
      continue

    if len(attributes['visibility']) == 0:
      print('Empty visibility for target %s', target)
      return 1

    visibility = set(attributes['visibility'])

    # Targets with visibility of '$cobalt_root/*' look like '//*' when printed by gn desc. This type
    # of target visibility is always considered okay since it is limited to cobalt core.
    visibility -= {'//*'}

    if len(visibility) == 0:
      # Proper visibility, limited to cobalt core repo
      continue

    # Any target with global visibility that isn't in the global_visibility_whitelist are errors.
    if '*' in visibility:
      globally_visibile.append(target)
      continue

    unfound_visibility = set()
    for vis in visibility:
      visibility_path = vis

      if vis in out_of_tree_visibility_whitelist:
        if target in out_of_tree_visibility_whitelist[vis]:
          continue

      # This converts GN targets to their directory.
      #
      # e.g. '//src/algorithms/random:durations' becomes 'src/algorithms/random'
      # e.g. '//src/algorithms/random/*' becomes 'src/algorithms/random/'
      if visibility_path.startswith('//'):
        visibility_path = visibility_path[2:]
        visibility_path = visibility_path.split(':')[0]
        visibility_path = visibility_path.split('*')[0]

      # Generate the absolute path from cobalt root referred to by the visibility_path.
      path_to_visibility_spec = os.path.join(cobalt_root, visibility_path)
      if os.path.isfile(path_to_visibility_spec) or os.path.isdir(
          path_to_visibility_spec):
        # This visibility spec has been found somewhere in the cobalt core repository. Explicit
        # visibilities for extant paths is always allowed.
        continue

      unfound_visibility.add(vis)

    for vis in unfound_visibility:
      out_of_tree_visibility.setdefault(vis, []).append(target)

  if len(globally_visibile) > 0:
    print('Found %d targets with global visibility:' % len(globally_visibile))
    for target in sorted(globally_visibile):
      print('  | %s' % target)
      errors += 1

  for vis in sorted(out_of_tree_visibility.keys()):
    targets = out_of_tree_visibility[vis]
    print('Found %s targets with out-of-tree visibility `%s`' %
          (len(targets), vis))
    for target in sorted(targets):
      print('  | %s' % target)
      errors += 1

  if errors > 0:
    print()
    print('Found %d Errors' % errors)
  else:
    print('No visibility issues found')
  return errors


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