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

"""Reads the contents of a package config file generated by the build and
  converts it to a real package_config.json file
"""

import argparse
import collections
import json
import os
import re
import sys

THIS_DIR = os.path.abspath(os.path.dirname(__file__))
sys.path += [os.path.join(THIS_DIR, '..', '..', '..', 'third_party', 'pyyaml', 'lib3')]
import yaml

DEFAULT_LANGUAGE_VERSION = '2.8'

Package = collections.namedtuple('Package', ['name', 'rootUri', 'languageVersion', 'packageUri'])


class PackageConfig:
  # The version of the package config.
  VERSION = 2

  # The name of the generator which gets written to the json output
  GENERATOR_NAME = os.path.basename(__file__)

  def __init__(self, packages):
    self.packages = packages

  def asdict(self):
    """Converts the package config to a dictionary"""
    return {
        'configVersion': self.VERSION,
        'packages': [p._asdict() for p in sorted(self.packages)],
        'generator': self.GENERATOR_NAME,
    }


def language_version_from_pubspec(pubspec):
  """Parse the content of a pubspec.yaml"""
  with open(pubspec) as pubspec:
    parsed = yaml.safe_load(pubspec)
    if not parsed:
      return DEFAULT_LANGUAGE_VERSION

    # If a format like sdk: '>=a.b' or sdk: 'a.b' is found, we'll use a.b.
    # In all other cases we default to "2.8"
    env_sdk = parsed.get('environment', {}).get('sdk', 'any')
    match = re.search(r'^(>=)?((0|[1-9]\d*)\.(0|[1-9]\d*))', env_sdk)
    if match:
      min_sdk_version = match.group(2)
    else:
      min_sdk_version = DEFAULT_LANGUAGE_VERSION

    return min_sdk_version


def collect_packages(items, relative_to):
  """Reads metadata produced by GN to create lists of packages and pubspecs.
        - items: a list of objects collected from gn
        - relative_to: The directory which the packages are relative to. This is
          the location that contains the package_config.json file

    Returns None if there was a problem parsing packages
    """
  packages = []
  pubspec_paths = []
  for item in items:
    if 'language_version' in item:
      language_version = item['language_version']
    elif 'pubspec_path' in item:
      pubspec_paths.append(item['pubspec_path'])
      language_version = language_version_from_pubspec(item['pubspec_path'])
    else:
      language_version = DEFAULT_LANGUAGE_VERSION

    package = Package(
        name=item['name'],
        rootUri=os.path.relpath(item['root_uri'], relative_to),
        languageVersion=language_version,
        packageUri=item['package_uri']
    )

    # TODO(fxbug.dev/56428): enable once we sort out our duplicate packages
    # for p in packages:
    #   if p.rootUri == package.rootUri:
    #     print('Failed to create package_config.json file')
    #     print('The following packages contain the same package root ' + p.rootUri)
    #     print('  - ' + p.rootUri)
    #     print('  - ' + package.rootUri)
    #     return None

    packages.append(package)

  return packages, pubspec_paths


def main():
  parser = argparse.ArgumentParser(description=__doc__)
  parser.add_argument('--input', help='Path to original package_config', required=True)
  parser.add_argument('--output', help='Path to the updated package_config', required=True)
  parser.add_argument('--root', help='Path to fuchsia root', required=True)
  parser.add_argument('--depfile', help='Path to the depfile', required=True)
  args = parser.parse_args()

  with open(args.input, 'r') as input_file:
    contents = json.load(input_file)

  output_dir = os.path.dirname(os.path.abspath(args.output))
  packages, pubspec_paths = collect_packages(contents, output_dir)
  if packages is None:
    return 1

  with open(args.depfile, 'w') as depfile:
    depfile.write('%s: %s' % (args.output, ' '.join(pubspec_paths)))

  with open(args.output, 'w') as output_file:
    package_config = PackageConfig(packages)
    json.dump(
        package_config.asdict(), output_file, indent=2, sort_keys=True, separators=(',', ': ')
    )

  return 0


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