#!/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')
        # Explicitly use the GNU_FORMAT because the current dart library
        # (v.3.0.0) does not support parsing other tar formats that allow for
        # filenames longer than 100 characters.
        with tarfile.open(tar_path, 'w', format=tarfile.GNU_FORMAT) 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())
