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