#!/usr/bin/env python3
# pylint: disable=line-too-long, subprocess-run-check, unused-argument
# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Convert Cargo metadata to ebuilds using cros-rust.

Used to add new Rust projects and building up ebuilds for the dependency tree.
"""

import argparse
from datetime import datetime
import json
import os
import re
import shutil
import subprocess
import sys

SCRIPT_NAME = 'cargo2ebuild.py'
AUTOGEN_NOTICE = '\n# This file was automatically generated by {}'.format(
    SCRIPT_NAME)

CRATE_DL_URI = 'https://crates.io/api/v1/crates/{PN}/{PV}/download'

# Required parameters
#   copyright_year: Current year for copyright assignment.
#   description: Description of the crates.
#   homepage: Homepage of the crates.
#   license: Ebuild compatible license string.
#   dependencies: Ebuild compatible dependency string.
#   autogen_notice: Autogenerated notification string.
EBUILD_TEMPLATE = \
"""# Copyright {copyright_year} The Chromium OS Authors. All rights reserved.
# Distributed under the terms of the GNU General Public License v2

EAPI="7"

CROS_RUST_REMOVE_DEV_DEPS=1

inherit cros-rust

DESCRIPTION="{description}"
HOMEPAGE="{homepage}"
SRC_URI="https://crates.io/api/v1/crates/${{PN}}/${{PV}}/download -> ${{P}}.crate"

LICENSE="{license}"
SLOT="${{PV}}/${{PR}}"
KEYWORDS="*"

{dependencies}{autogen_notice}
"""

# Required parameters:
#   copyright_year: Current year for copyright assignment.
#   crate_features: Features to add to this empty crate.
#   autogen_notice: Autogenerated notification string.
EMPTY_CRATE = \
"""# Copyright {copyright_year} The Chromium OS Authors. All rights reserved.
# Distributed under the terms of the GNU General Public License v2

EAPI="7"

CROS_RUST_EMPTY_CRATE=1
{crate_features}
inherit cros-rust

DESCRIPTION="Empty crate"
HOMEPAGE=""

LICENSE="BSD-Google"
SLOT="${{PV}}/${{PR}}"
KEYWORDS="*"
{autogen_notice}
"""

LICENSES = {
    'Apache-2.0': 'Apache-2.0',
    'MIT': 'MIT',
    'BSD-3-Clause': 'BSD',
    '0BSD': '0BSD',
    'ISC': 'ISC',
}

VERSION_RE = (
    '^(?P<dep>[\\^~=])?'  # Dependency type: ^, ~, =
    '(?P<major>[0-9]+|[*])'  # Major version (can be *)
    '(.(?P<minor>[0-9]+|[*]))?'  # Minor version
    '(.(?P<patch>[0-9]+|[*]))?'  # Patch version
    '([+\\-].*)?$'  # Any semver values beyond patch version
)


def prepare_staging(args):
    """Prepare staging directory."""
    sdir = args.staging_dir
    dirs = [
        os.path.join(sdir, 'ebuild', 'dev-rust'),
        os.path.join(sdir, 'crates')
    ]
    for d in dirs:
        os.makedirs(d, exist_ok=True)


def load_metadata(manifest_path):
    """Run cargo metadata and get metadata for build."""
    cwd = os.path.dirname(manifest_path)
    cmd = [
        'cargo', 'metadata', '--format-version', '1', '--manifest-path',
        manifest_path
    ]
    output = subprocess.check_output(cmd, cwd=cwd)

    return json.loads(output)


def get_crate_path(package, staging_dir):
    """Get path to crate in staging directory."""
    return os.path.join(
        staging_dir, 'crates', '{}-{}.crate'.format(package['name'],
                                                    package['version']))


def get_clean_crate_name(package):
    """Clean up crate name to {name}-{major}.{minor}.{patch}."""
    return '{}-{}.crate'.format(package['name'],
                                get_clean_package_version(package))


def version_to_tuple(name, version, missing=-1):
    """Extract dependency type and semver from a given version string."""
    def version_to_int(num):
        if not num or num == '*':
            return missing
        return int(num)

    m = re.match(VERSION_RE, version)
    if not m:
        print('{} failed to parse dep version: {}'.format(name, version))

    dep = m.group('dep')
    major = m.group('major')
    minor = m.group('minor')
    patch = m.group('patch')

    has_star = any([x == '*' for x in [major, minor, patch]])

    major = version_to_int(major)
    minor = version_to_int(minor)
    patch = version_to_int(patch)

    if has_star:
        dep = '~'
    elif not dep:
        dep = '^'

    return (dep, major, minor, patch)


def get_clean_package_version(package):
    """Get package version in the format {major}.{minor}.{patch}."""
    (_, major, minor, patch) = version_to_tuple(package['name'],
                                                package['version'],
                                                missing=0)
    return '{}.{}.{}'.format(major, minor, patch)


def get_ebuild_path(package, staging_dir, make_dir=False):
    """Get path to ebuild in given directory."""
    ebuild_path = os.path.join(
        staging_dir, 'dev-rust', package['name'],
        '{}-{}.ebuild'.format(package['name'],
                              get_clean_package_version(package)))

    if make_dir:
        os.makedirs(os.path.dirname(ebuild_path), exist_ok=True)

    return ebuild_path


def download_package(package, staging_dir):
    """Download the crate from crates.io."""
    dl_uri = CRATE_DL_URI.format(PN=package['name'], PV=package['version'])
    crate_path = get_crate_path(package, staging_dir)

    # Already downloaded previously
    if os.path.isfile(crate_path):
        return

    ret = subprocess.run(['curl', '-L', dl_uri, '-o', crate_path],
                   stdout=subprocess.DEVNULL,
                   stderr=subprocess.DEVNULL).returncode

    if ret:
        print('{} failed to download: {}'.format(dl_uri, ret))


def get_description(package):
    """Get a description of the crate from metadata."""
    # pylint: disable=invalid-string-quote
    if package.get('description', None):
        desc = package['description'].replace('`', '\'').replace('"', '\'')
        return desc.rstrip('\n')

    return ''


def get_homepage(package):
    """Get the homepage of the crate from metadata or use crates.io."""
    if package.get('homepage', None):
        return package['homepage']

    return 'https://crates.io/crates/{}'.format(package['name'])


def convert_license(cargo_license, package):
    """Convert licenses from cargo to a format usable in ebuilds."""
    cargo_license = '' if not cargo_license else cargo_license
    has_or = ' OR ' in cargo_license
    delim = ' OR ' if has_or else '/'

    found = cargo_license.split(delim)
    licenses_or = []
    for f in found:
        if f in LICENSES:
            licenses_or.append(LICENSES[f])

    if not licenses_or:
        print('{} is missing an appropriate license: {}'.format(
            package['name'], license))
        return "$(die 'Please replace with appropriate license')"

    if len(licenses_or) > 1:
        lstr = '|| ( {} )'.format(' '.join(licenses_or))
    else:
        lstr = licenses_or[0]

    return lstr


def convert_dependencies(dependencies, package, optional_packages):
    """Convert dependencies from metadata into the ebuild format."""
    def caret_to_ebuild(info):
        prefix = '>=dev-rust/{name}-{major}.{minor}.{patch}:='.format(**info)
        suffix = '<dev-rust/{name}-{major_1}'.format(**info)

        if info['minor'] == -1:
            prefix = '>=dev-rust/{name}-{major}:='.format(**info)
        elif info['patch'] == -1:
            prefix = '>=dev-rust/{name}-{major}.{minor}:='.format(**info)

        if info['major'] == 0:
            suffix = '<dev-rust/{name}-{major}.{minor_1}'.format(**info)

        return '{} {}'.format(prefix, suffix)

    def tilde_to_ebuild(info):
        prefix = '>=dev-rust/{name}-{major}.{minor}.{patch}:='.format(**info)
        suffix = '<dev-rust/{name}-{major}.{minor_1}'.format(**info)
        ebuild = '{} {}'.format(prefix, suffix)

        if info['minor'] == -1:
            ebuild = '=dev-rust/{name}-{major}*:='.format(**info)
        elif info['patch'] == -1:
            ebuild = '=dev-rust/{name}-{major}.{minor}*:='.format(**info)

        return ebuild

    def dep_to_ebuild(name, dep_type, major, minor, patch):
        info = {
            'name': name,
            'major': major,
            'minor': minor,
            'patch': patch,
            'major_1': major + 1,
            'minor_1': minor + 1,
            'patch_1': patch + 1
        }

        if dep_type == '^':
            return caret_to_ebuild(info)
        if dep_type == '~':
            return tilde_to_ebuild(info)

        # Remaining dep type is =
        return '=dev-rust/{name}-{major}.{minor}.{patch}:='.format(**info)

    deps = []
    for dep in dependencies:
        # Skip all dev dependencies. We will still handle normal and build deps.
        if dep.get('kind', None) == 'dev':
            continue

        # Optional dependencies get empty packages created
        if dep.get('optional', None):
            optional_packages[dep['name']] = {
                    'name': dep['name'],
                    'version': dep['req'],
                    'features': dep['features'],
            }

        # Convert requirement to version tuple
        (deptype, major, minor, patch) = version_to_tuple(dep['name'], dep['req'])
        ebuild = dep_to_ebuild(dep['name'], deptype, major, minor, patch)
        deps.append('\t{}'.format(ebuild))

    if not deps:
        return ''

    # Add DEPEND= into template with all dependencies
    # RDEPEND="${DEPEND}" required for race in cros-rust
    fmtstring = 'DEPEND="\n{}\n"\nRDEPEND="${{DEPEND}}"\n'
    return fmtstring.format('\n'.join(deps))


def package_ebuild(package, ebuild_dir, optional_packages):
    """Create ebuild from metadata and write to ebuild directory."""
    ebuild_path = get_ebuild_path(package, ebuild_dir, make_dir=True)

    autogen_notice = AUTOGEN_NOTICE

    # Check if version matches clean version or modify the autogen notice
    if package['version'] != get_clean_package_version(package):
        autogen_notice = '\n'.join([
            autogen_notice,
            '# ${{PV}} was changed from the original {}'.format(
                package['version'])
        ])

    dependencies = convert_dependencies(package['dependencies'], package,
                                        optional_packages)
    template_info = {
        'copyright_year': datetime.now().year,
        'description': get_description(package),
        'homepage': get_homepage(package),
        'license': convert_license(package['license'], package),
        'dependencies': dependencies,
        'autogen_notice': autogen_notice,
    }

    with open(ebuild_path, 'w') as ebuild:
        ebuild.write(EBUILD_TEMPLATE.format(**template_info))


def upload_gsutil(package, staging_dir, no_upload=False):
    """Upload crate to distfiles."""
    if no_upload:
        return

    crate_path = get_crate_path(package, staging_dir)
    crate_name = get_clean_crate_name(package)
    ret = subprocess.run([
        'gsutil', 'cp', '-a', 'public-read', crate_path,
        'gs://chromeos-localmirror/distfiles/{}'.format(crate_name)
    ]).returncode

    if ret:
        print('{} failed to upload to chromeos-localmirror: {}'.format(
            crate_name, ret))


def update_ebuild(package, ebuild_dir, target_dir):
    """Update ebuild with generated one and generate MANIFEST."""
    ebuild_src = get_ebuild_path(package, ebuild_dir)
    ebuild_dest = get_ebuild_path(package, target_dir, make_dir=True)

    shutil.copy(ebuild_src, ebuild_dest)

    # Generate manifest w/ ebuild digest
    ret = subprocess.run(['ebuild', ebuild_dest, 'digest']).returncode
    if ret:
        print('ebuild {} digest failed: {}'.format(ebuild_dest, ret))


def process_package(package, args, optional_packages):
    """Process each package listed in the metadata."""
    staging_dir = args.staging_dir
    ebuild_dir = os.path.join(staging_dir, 'ebuild')
    target_dir = args.target_dir

    download_package(package, staging_dir)
    package_ebuild(package, ebuild_dir, optional_packages)

    if not args.dry_run and package['name'] not in args.skip:
        upload_gsutil(package, staging_dir, no_upload=args.no_upload)
        update_ebuild(package, ebuild_dir, target_dir)

def process_empty_package(empty_package, args):
    """Process packages that should generate empty ebuilds."""
    staging_dir = args.staging_dir
    ebuild_dir = os.path.join(staging_dir, 'ebuild')
    target_dir = args.target_dir

    ebuild_src = get_ebuild_path(empty_package, ebuild_dir, make_dir=True)
    ebuild_dest = get_ebuild_path(empty_package, target_dir, make_dir=True)

    crate_features = ''
    if empty_package.get('features', None):
        crate_features = 'CROS_RUST_EMPTY_CRATE_FEATURES=( {} )'.format(
            ' '.join(['"{}"'.format(x) for x in empty_package['features']]))

    template_info = {
        'copyright_year': datetime.now().year,
        'crate_features': crate_features,
        'autogen_notice': AUTOGEN_NOTICE,
    }

    with open(ebuild_src, 'w') as ebuild:
        ebuild.write(EMPTY_CRATE.format(**template_info))

    if not args.dry_run and empty_package['name'] not in args.skip:
        shutil.copy(ebuild_src, ebuild_dest)

def check_if_package_is_required(empty_package, args):
    """Check if an empty package already has a non-empty ebuild."""
    ebuild_dest = get_ebuild_path(empty_package, args.target_dir, make_dir=False)
    ebuild_target_dir = os.path.dirname(ebuild_dest)

    # Find all ebuilds in ebuild_target dir and confirm they have
    # CROS_RUST_EMPTY_CRATE in them. If they do not, they need to be manually
    # handled.
    for root, _, files in os.walk(ebuild_target_dir):
        for efile in files:
            if not efile.endswith('.ebuild'):
                continue

            with open(os.path.join(root, efile), 'r') as ebuild:
                if 'CROS_RUST_EMPTY_CRATE' not in ebuild.read():
                    print('{} was not an empty crate.'.format(efile))
                    return True

    return False

def main(argv):
    """Convert dependencies from Cargo.toml into ebuilds."""
    args = parse_args(argv)

    prepare_staging(args)

    processed_packages = {}
    optional_packages = {}
    metadata = load_metadata(args.manifest_path)
    for p in metadata['packages']:
        process_package(p, args, optional_packages)
        processed_packages[p['name']] = True

    for key in optional_packages:
        if key not in processed_packages and not check_if_package_is_required(
                optional_packages[key], args):
            process_empty_package(optional_packages[key], args)


def parse_args(argv):
    """Parse the command-line arguments."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '-s',
        '--staging-dir',
        required=True,
        help='Staging directory for temporary and generated files')

    parser.add_argument(
        '-d',
        '--dry-run',
        action='store_true',
        help='Generate dependency tree but do not upload anything')

    parser.add_argument('-t',
                        '--target-dir',
                        help='Path to chromiumos-overlay')

    parser.add_argument('-k',
                        '--skip',
                        action='append',
                        help='Skip these packages when updating ebuilds')
    parser.add_argument('-n',
                        '--no-upload',
                        action='store_true',
                        help='Skip uploading crates to distfiles')

    parser.add_argument('manifest_path',
                        help='Cargo.toml used to generate ebuilds.')

    args = parser.parse_args(argv)

    # Require target directory if not dry run
    if not args.target_dir and not args.dry_run:
        raise Exception('Target directory must be set unless dry-run is True.')

    if not args.skip:
        args.skip = []

    return args


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
