#!/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 os
import sys
# 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())
