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