# Copyright 2021 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Copies files from CIPD to a specified directory.

By default, Pigweed installs packages from a manifest file to a CIPD
subdirectory as part of environment setup. This script will copy files from this
directory into a specified output directory.

Here's an example of how to use this script:

Let's say you have a package with a static library:

CIPD path: `pigweed/third_party/libsomething`
Files:
  ./libsomething/include/something.h
  ./libsomething/libsomething.a

And this package was referenced in my_project_packages.json, which was provided
as a --cipd-package-file in your bootstrap script.

To copy the static libraryto $PW_PROJECT_ROOT/static_libraries, you'd have an
invocation something like this:

copy_from_cipd --package-name=pigweed/third_party/libsomething \
               --mainfest=$PW_PROJECT_ROOT/tools/my_project_packages.json \
               --file=libsomething/libsomething.a \
               --out=$PW_PROJECT_ROOT/static_libraries
"""

import argparse
import json
import logging
import os
import shutil
import subprocess
import sys
from pathlib import Path

import pw_env_setup.cipd_setup.update

logger = logging.getLogger(__name__)


def parse_args():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--verbose',
                        '-v',
                        help='Verbose output',
                        action='store_true')
    parser.add_argument('--manifest',
                        required=True,
                        type=Path,
                        help='Path to CIPD JSON manifest file')
    parser.add_argument('--out-dir',
                        type=Path,
                        default='.',
                        help='Output folder to copy the specified file to')
    parser.add_argument('--package-name',
                        required=True,
                        help='The CIPD package name')
    # TODO(pwbug/334) Support multiple values for --file.
    parser.add_argument('--file',
                        required=True,
                        type=Path,
                        help='Path of the file to copy from the CIPD package. '
                        'This is relative to the CIPD package root of the '
                        'provided manifest.')
    parser.add_argument('--cipd-package-root',
                        type=Path,
                        help="Path to the root of the package's install "
                        'directory. This is usually at '
                        'PW_{manifest name}_CIPD_INSTALL_DIR')
    return parser.parse_args()


def check_version(manifest, cipd_path, package_name):
    base_package_name = os.path.basename(package_name)
    instance_id_path = os.path.join(cipd_path, '.versions',
                                    f'{base_package_name}.cipd_version')
    with open(instance_id_path, 'r') as ins:
        instance_id = json.load(ins)['instance_id']

    with open(manifest, 'r') as ins:
        data = json.load(ins)
    # TODO(pwbug/599) Always assume this is a dict.
    if isinstance(data, dict):
        data = data['packages']

    path = None
    expected_version = None
    for entry in data:
        if package_name in entry['path']:
            path = entry['path']
            expected_version = entry['tags'][0]
    if not path:
        raise LookupError(f'failed to find {package_name} entry')

    cmd = ['cipd', 'describe', path, '-version', instance_id]
    output = subprocess.check_output(cmd).decode()
    if expected_version not in output:
        pw_env_setup.cipd_setup.update.update(
            'cipd', (manifest, ), os.environ['PW_CIPD_INSTALL_DIR'],
            os.environ['CIPD_CACHE_DIR'])


def main():
    args = parse_args()

    if args.verbose:
        logger.setLevel(logging.DEBUG)

    # Try to infer CIPD install root from the manifest name.
    if args.cipd_package_root is None:
        file_base_name = args.manifest.stem
        args.cipd_var = 'PW_{}_CIPD_INSTALL_DIR'.format(file_base_name.upper())
        try:
            args.cipd_package_root = os.environ[args.cipd_var]
        except KeyError:
            logger.error(
                "The %s environment variable isn't set. Did you forget to run "
                '`. ./bootstrap.sh`? Is the %s manifest installed to a '
                'different path?', args.cipd_var, file_base_name)
            sys.exit(1)

    check_version(args.manifest, args.cipd_package_root, args.package_name)

    shutil.copyfile(os.path.join(args.cipd_package_root, args.file),
                    os.path.join(args.out_dir, args.file))


if __name__ == '__main__':
    logging.basicConfig()
    main()
