#!/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
#
# DO NOT ADD ANY NEW ENTRIES TO THIS DICT
out_of_tree_visibility_whitelist = {
    '//src/cobalt/bin/*': [
        '//src/lib/clearcut:clearcut',
        '//src/lib/statusor:statusor',
        '//src/lib/util:clock',
        '//src/lib/util:datetime_util',
        '//src/lib/util:file_util',
        '//src/lib/util:pem_util',
        '//src/lib/util:posix_file_system',
        '//src/logger:fake_logger',
        '//src/logger:logger_test_utils',
        '//src/registry:cobalt_registry_proto',
        '//src/system_data:configuration_data',
        '//src/system_data:system_data',
    ],
    '//src/cobalt/bin/app:lib': ['//src/logger:logger'],
    '//src/cobalt/bin/system-metrics/*': ['//src/registry:buckets_config'],
    '//src/ui/scenic/*': ['//src/registry:buckets_config'],
}


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