#!/usr/bin/env python3.8
# 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
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())
