#!/usr/bin/env fuchsia-vendored-python
# Copyright 2023 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.

import argparse
import zipfile
import subprocess
import os
import shutil
import tempfile


def zip_dir(dir, zip_file):
    for root, _dirs, files in os.walk(dir):
        for file in files:
            path = os.path.join(root, file)
            zip_file.write(path, os.path.relpath(path, dir))


# rmtree manually removes all subdirectories and files instead of using
# shutil.rmtree, to avoid registering spurious reads on stale
# subdirectories. See https://fxbug.dev/74084.
def rmtree(dir):
    if not os.path.exists(dir):
        return
    for root, dirs, files in os.walk(dir, topdown=False):
        for file in files:
            os.unlink(os.path.join(root, file))
        for dir in dirs:
            full_path = os.path.join(root, dir)
            if os.path.islink(full_path):
                os.unlink(full_path)
            else:
                os.rmdir(full_path)


def prepare_dirs(repo_dir):
    path = os.path.join(repo_dir, 'repository')
    os.makedirs(path)

    return {'root': repo_dir, 'repository': path}


# `package-tool repository publish` expects the following inputs in its in/out directory:
# - `keys/{snapshot|targets|timestamp}.json` containing private metadata keys;
# - `repository/{{version-num}}.root.json` containing versioned root metadata;
# - `repository/root.json` containing default root metadata.
def prepare_publish(args, dirs):
    for root_metadata_path in args.root_metadata:
        shutil.copy(root_metadata_path, dirs['repository'])
    shutil.copy(
        args.default_root_metadata,
        '{}/{}'.format(dirs['repository'], 'root.json'))


def package_tool_publish(args, dirs, depfile):
    cmd_args = [
        args.package_tool,
        'repository',
        'publish',
        '--trusted-keys',
        args.trusted_keys,
        '--trusted-root',
        '{}/{}'.format(dirs['repository'], 'root.json'),
        '--package-list',
        args.input,
        '--depfile',
        args.depfile,
    ]

    if args.delivery_blob_type:
        cmd_args.extend(['--delivery-blob-type', args.delivery_blob_type])

    cmd_args.append(dirs['root'])

    subprocess.run(cmd_args, check=True)


def main(args):
    with tempfile.TemporaryDirectory(
            dir=os.path.dirname(args.output)) as gendir:
        dirs = prepare_dirs(gendir)

        # Prepare for `package-tool repository publish` and gather deps associated with preparations.
        prepare_publish(args, dirs)

        depfile = os.path.join(gendir, 'deps')

        # Invoke `package-tool repository publish` and gather deps associated with invocation.
        package_tool_publish(args, dirs, depfile)

        # Output repository directory to zip file.
        with zipfile.ZipFile(args.output, 'w',
                             zipfile.ZIP_DEFLATED) as zip_file:
            zip_dir(dirs['repository'], zip_file)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        'Creates a zip archive of the TUF repository output by `package-tool repository publish`'
    )
    parser.add_argument(
        '--package-tool',
        help='path to the package-tool executable',
        required=True)
    parser.add_argument(
        '--trusted-keys',
        help=
        'path to a keys directory to be consumed by `package-tool repository publish`'
    )
    parser.add_argument(
        '--root-metadata',
        help='path to a root metadata file to be used in the TUF repository',
        action='append')
    parser.add_argument(
        '--default-root-metadata',
        help='path to the default TUF root metadata file',
        required=True)
    parser.add_argument(
        '--input',
        help='path to `package-tool repository publish` file input',
        required=True)
    parser.add_argument(
        '--delivery-blob-type', help='the type of delivery blob to generate')
    parser.add_argument('--depfile', help='generate a depfile', required=True)
    parser.add_argument('--output', help='path output zip file', required=True)
    main(parser.parse_args())
