#!/usr/bin/env python3.8
# Copyright 2020 The Fuchsia 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

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 """
    import 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()

    sys.path += [os.path.join(args.root, 'third_party', 'pyyaml', 'lib3')]

    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())
