#!/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"""

from __future__ import print_function

import subprocess
import json
import os

# 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/cobalt/bin/utils:fuchsia_http_client': [
        '//src/lib/statusor:statusor',
    ],
}


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())
