#!/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.

import argparse
import json
import os
import re
import shutil
import sys
import tarfile


class GatherPackageDeps:
    """Helper class to take a `package_manifest.json` and copy all files referenced
    into an archive that will then be available at runtime.

    Args:
      package_json_path (string): An absolute path to the package's `package_manifest.json` file.
      meta_far_path (string): An absolute path to the package's `meta.far` file.
      output_dir (string): The absolute path to the directory that this should output into.

    Raises: ValueError if any parameter is empty.
    """

    # Selects everything that comes after '/' and/or any number of '../'.
    path_stripper = re.compile(r'(?:(?:\.\.\/)+)?\/?(.+)')

    def __init__(self, package_json_path, meta_far_path, output_dir):
        if package_json_path and os.path.exists(package_json_path):
            self.package_json_path = package_json_path
        else:
            raise ValueError('package_json_path must be to a valid file')

        if meta_far_path and os.path.exists(meta_far_path):
            self.meta_far_path = meta_far_path
        else:
            raise ValueError('meta_far_path must be to a valid file')

        if output_dir:
            self.output_dir = output_dir
        else:
            raise ValueError('output_dir cannot be empty')

    def parse_package_json(self):
        manifest_dict = {}
        with open(self.package_json_path) as f:
            data = json.load(f)
            for file in data['blobs']:
                if file['path'].startswith('meta/'):
                    continue
                manifest_dict[file['path']] = file['source_path']
        return manifest_dict

    def copy_meta_far(self):
        shutil.copyfile(
            self.meta_far_path, os.path.join(self.output_dir, 'meta.far'))

    def copy_to_output_dir(self, manifest_dict):
        for archive_path, source_path in manifest_dict.items():
            # Some `source_path`s are prefixed with a couple of `../`'s or are absolute paths.
            # Examples:
            #    "../../prebuilt/third_party/clang/linux-x64/lib/aarch64-unknown-fuchsia/c++/libc++.so.2"
            #    "/root/to/fuchsia/out/core.x64-host_asan/obj/topaz/runtime/flutter_runner/flutter_aot_runner.meta/blobs/2ae9bee944d30eeec29608eb2f5e21df71f92bdb8f75f8c2ea1a2cd8d273915b"
            #
            # All of these files must end up in our `output_dir`, where `../`s are meaningless and
            # wrong, and absolute paths are definitely wrong. All of these must be cleaned up into
            # useable relative paths - relative to the `output_dir`.
            # The above examples should become:
            #    "prebuilt/third_party/clang/linux-x64/lib/aarch64-unknown-fuchsia/c++/libc++.so.2"
            #    "root/to/fuchsia/out/core.x64-host_asan/obj/topaz/runtime/flutter_runner/flutter_aot_runner.meta/blobs/2ae9bee944d30eeec29608eb2f5e21df71f92bdb8f75f8c2ea1a2cd8d273915b"
            #
            # These are the paths as they will appear within the output `tar` file and will be how
            # they are referenced within the manifest file.
            m = self.path_stripper.match(source_path)
            out_path = os.path.join(self.output_dir, m.group(1))
            os.makedirs(os.path.dirname(out_path), exist_ok=True)
            shutil.copyfile(source_path, out_path)
            manifest_dict[archive_path] = m.group(1)

    def write_new_manifest(self, manifest_dict):
        with open(os.path.join(self.output_dir, 'package.manifest'), 'w') as f:
            for archive_path, source_path in manifest_dict.items():
                f.write(archive_path + '=' + source_path + '\n')
            f.write('meta/package=meta.far\n')

    def archive_output(self):
        tar_path = os.path.join(self.output_dir, 'package.tar')
        with tarfile.open(tar_path, 'w') as tar:
            for root, _, files in os.walk(self.output_dir):
                for name in files:
                    relative_dir = os.path.relpath(root, self.output_dir)
                    input_path = os.path.join(root, name)
                    relative_path = os.path.join(relative_dir, name)
                    if input_path == tar_path:
                        continue
                    tar.add(input_path, arcname=relative_path)

    def run(self):
        manifest_dict = self.parse_package_json()
        self.copy_meta_far()
        self.copy_to_output_dir(manifest_dict)
        self.write_new_manifest(manifest_dict)
        self.archive_output()


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--package_json_path',
        required=True,
        help=
        'The path to the package_manifest.json generated by a `fuchsia_package`.'
    )
    parser.add_argument(
        '--meta_far_path',
        required=True,
        help='The path to the package\'s meta.far.')
    parser.add_argument(
        '--output_dir',
        required=True,
        help=
        'The path to where the new manifest and all required files will be copied to.'
    )
    args = parser.parse_args()

    try:
        gatherer = GatherPackageDeps(
            args.package_json_path, args.meta_far_path, args.output_dir).run()
    except Exception as e:
        print('GatherPackageDeps errored during run: %s' % e)
        return 1

    return 0


if __name__ == '__main__':
    sys.exit(main())
