#!/usr/bin/env python3
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Lint as: python3
"""Prints out available java targets.

Examples:
# List GN target for bundles:
build/android/list_java_targets.py -C out/Default --type android_app_bundle \
--gn-labels

# List all android targets with types:
build/android/list_java_targets.py -C out/Default --print-types

# Build all apk targets:
build/android/list_java_targets.py -C out/Default --type android_apk | xargs \
autoninja -C out/Default

# Show how many of each target type exist:
build/android/list_java_targets.py -C out/Default --stats

"""

import argparse
import collections
import json
import logging
import os
import shutil
import subprocess
import sys

_SRC_ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), '..',
                                          '..'))
sys.path.append(os.path.join(_SRC_ROOT, 'build', 'android'))
from pylib import constants

_VALID_TYPES = (
    'android_apk',
    'android_app_bundle',
    'android_app_bundle_module',
    'android_assets',
    'android_resources',
    'dist_aar',
    'dist_jar',
    'group',
    'java_annotation_processor',
    'java_binary',
    'java_library',
    'robolectric_binary',
    'system_java_library',
)


def _resolve_ninja():
  # Prefer the version on PATH, but fallback to known version if PATH doesn't
  # have one (e.g. on bots).
  if shutil.which('ninja') is None:
    return os.path.join(_SRC_ROOT, 'third_party', 'ninja', 'ninja')
  return 'ninja'


def _resolve_autoninja():
  # Prefer the version on PATH, but fallback to known version if PATH doesn't
  # have one (e.g. on bots).
  if shutil.which('autoninja') is None:
    return os.path.join(_SRC_ROOT, 'third_party', 'depot_tools', 'autoninja')
  return 'autoninja'


def _run_ninja(output_dir, args, j_value=None, quiet=False):
  if j_value:
    cmd = [_resolve_ninja(), '-j', j_value]
  else:
    cmd = [_resolve_autoninja()]
  cmd += [
      '-C',
      output_dir,
  ]
  cmd.extend(args)
  logging.info('Running: %r', cmd)
  if quiet:
    subprocess.run(cmd, check=True, capture_output=True)
  else:
    subprocess.run(cmd, check=True, stdout=sys.stderr)


def _query_for_build_config_targets(output_dir):
  # Query ninja rather than GN since it's faster.
  # Use ninja rather than autoninja to avoid extra output if user has set the
  # NINJA_SUMMARIZE_BUILD environment variable.
  cmd = [_resolve_ninja(), '-C', output_dir, '-t', 'targets']
  logging.info('Running: %r', cmd)
  ninja_output = subprocess.run(cmd,
                                check=True,
                                capture_output=True,
                                encoding='ascii').stdout
  ret = []
  SUFFIX = '__build_config_crbug_908819'
  SUFFIX_LEN = len(SUFFIX)
  for line in ninja_output.splitlines():
    ninja_target = line.rsplit(':', 1)[0]
    # Ignore root aliases by ensuring a : exists.
    if ':' in ninja_target and ninja_target.endswith(SUFFIX):
      ret.append(f'//{ninja_target[:-SUFFIX_LEN]}')
  return ret


def _query_json(*, json_dict: dict, query: str, path: str):
  """Traverses through the json dictionary according to the query.

  If at any point a key does not exist, return the empty string, but raise an
  error if a key exists but is the wrong type.

  This is roughly equivalent to returning
  json_dict[queries[0]]?[queries[1]]?...[queries[N]]? where the ? means that if
  the key doesn't exist, the empty string is returned.

  Example:
  Given json_dict = {'a': {'b': 'c'}}
  - If queries = ['a', 'b']
    Return: 'c'
  - If queries = ['a', 'd']
    Return ''
  - If queries = ['x']
    Return ''
  - If queries = ['a', 'b', 'x']
    Raise an error since json_dict['a']['b'] is the string 'c' instead of an
    expected dict that can be indexed into.

  Returns the final result after exhausting all the queries.
  """
  queries = query.split('.')
  value = json_dict
  try:
    for key in queries:
      value = value.get(key)
      if value is None:
        return ''
  except AttributeError as e:
    raise Exception(
        f'Failed when attempting to get {queries} from {path}') from e
  return value


class _TargetEntry:

  def __init__(self, gn_target):
    assert gn_target.startswith('//'), f'{gn_target} does not start with //'
    assert ':' in gn_target, f'Non-root {gn_target} required'
    self.gn_target = gn_target
    self._build_config = None

  @property
  def ninja_target(self):
    return self.gn_target[2:]

  @property
  def ninja_build_config_target(self):
    return self.ninja_target + '__build_config_crbug_908819'

  @property
  def build_config_path(self):
    """Returns the filepath of the project's .build_config.json."""
    ninja_target = self.ninja_target
    # Support targets at the root level. e.g. //:foo
    if ninja_target[0] == ':':
      ninja_target = ninja_target[1:]
    subpath = ninja_target.replace(':', os.path.sep) + '.build_config.json'
    return os.path.join(constants.GetOutDirectory(), 'gen', subpath)

  def build_config(self):
    """Reads and returns the project's .build_config.json JSON."""
    if not self._build_config:
      with open(self.build_config_path) as jsonfile:
        self._build_config = json.load(jsonfile)
    return self._build_config

  def get_type(self):
    """Returns the target type from its .build_config.json."""
    return self.build_config()['deps_info']['type']

  def proguard_enabled(self):
    """Returns whether proguard runs for this target."""
    # Modules set proguard_enabled, but the proguarding happens only once at the
    # bundle level.
    if self.get_type() == 'android_app_bundle_module':
      return False
    return self.build_config()['deps_info'].get('proguard_enabled', False)


def main():
  parser = argparse.ArgumentParser(
      description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
  parser.add_argument('-C',
                      '--output-directory',
                      help='If outdir is not provided, will attempt to guess.')
  parser.add_argument('--gn-labels',
                      action='store_true',
                      help='Print GN labels rather than ninja targets')
  parser.add_argument(
      '--nested',
      action='store_true',
      help='Do not convert nested targets to their top-level equivalents. '
      'E.g. Without this, foo_test__apk -> foo_test')
  parser.add_argument('--print-types',
                      action='store_true',
                      help='Print type of each target')
  parser.add_argument(
      '--print-build-config-paths',
      action='store_true',
      help='Print path to the .build_config.json of each target')
  parser.add_argument('--build',
                      action='store_true',
                      help='Build all .build_config.json files.')
  parser.add_argument('--type',
                      action='append',
                      help='Restrict to targets of given type',
                      choices=_VALID_TYPES)
  parser.add_argument('--stats',
                      action='store_true',
                      help='Print counts of each target type.')
  parser.add_argument('--proguard-enabled',
                      action='store_true',
                      help='Restrict to targets that have proguard enabled.')
  parser.add_argument('--query',
                      help='A dot separated string specifying a query for a '
                      'build config json value of each target. Example: Use '
                      '--query deps_info.unprocessed_jar_path to show a list '
                      'of all targets that have a non-empty deps_info dict and '
                      'non-empty "unprocessed_jar_path" value in that dict.')
  parser.add_argument('-j', help='Use -j with ninja instead of autoninja.')
  parser.add_argument('-v', '--verbose', default=0, action='count')
  parser.add_argument('-q', '--quiet', default=0, action='count')
  args = parser.parse_args()

  args.build |= bool(args.type or args.proguard_enabled or args.print_types
                     or args.stats or args.query)

  logging.basicConfig(level=logging.WARNING + 10 * (args.quiet - args.verbose),
                      format='%(levelname).1s %(relativeCreated)6d %(message)s')

  if args.output_directory:
    constants.SetOutputDirectory(args.output_directory)
  constants.CheckOutputDirectory()
  output_dir = constants.GetOutDirectory()

  # Query ninja for all __build_config_crbug_908819 targets.
  targets = _query_for_build_config_targets(output_dir)
  entries = [_TargetEntry(t) for t in targets]

  if args.build:
    logging.warning('Building %d .build_config.json files...', len(entries))
    _run_ninja(output_dir, [e.ninja_build_config_target for e in entries],
               j_value=args.j,
               quiet=args.quiet)

  if args.type:
    entries = [e for e in entries if e.get_type() in args.type]

  if args.proguard_enabled:
    entries = [e for e in entries if e.proguard_enabled()]

  if args.stats:
    counts = collections.Counter(e.get_type() for e in entries)
    for entry_type, count in sorted(counts.items()):
      print(f'{entry_type}: {count}')
  else:
    for e in entries:
      if args.gn_labels:
        to_print = e.gn_target
      else:
        to_print = e.ninja_target

      # Convert to top-level target
      if not args.nested:
        to_print = to_print.replace('__test_apk', '').replace('__apk', '')

      if args.print_types:
        to_print = f'{to_print}: {e.get_type()}'
      elif args.print_build_config_paths:
        to_print = f'{to_print}: {e.build_config_path}'
      elif args.query:
        value = _query_json(json_dict=e.build_config(),
                            query=args.query,
                            path=e.build_config_path)
        if not value:
          continue
        to_print = f'{to_print}: {value}'

      print(to_print)


if __name__ == '__main__':
  main()
