#!/usr/bin/env fuchsia-vendored-python
# Copyright 2018 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.
"""Merge the content of two SDKs into a new one.

Use either --output-archive or --output-directory to indicate the output.
Note that it is possible to use both at the same time.

To specify inputs, there are two ways due to compatibility:

The legacy way (only supports two inputs):

  * Use either --first-archive or --first-directory to indicate the first input.
  * Use either --second-archive or --second-directory to indicate the second input.

The new way:

  * Use either --input-archive or --input-directory to indicate an input.
  * as many times as necessary, which means at least twice, since there is no
    point in merging a single input.

It is possible to use a single input and a single output, in particular to
create an archive from a single input directory, without any merge operation
as in:

  merge.py --input-directory DIR --output-archive ARCHIVE

Another use case if filtering any stale artifacts from an input directory
since the merge/copy will only include files listed from in the SDK metadata file,
for example:

  INPUT_DIR=out/default/sdk/exported/core
  touch $INPUT_DIR/UNWANTED_FILE
  merge.py --input-directory $INPUT_DIR --output-directory /tmp/FOO

Will not create /tmp/FOO/UNWANTED_FILE since it is not listed in the SDK manifest.
"""

# See https://stackoverflow.com/questions/33533148/how-do-i-type-hint-a-method-with-the-type-of-the-enclosing-class
from __future__ import annotations

import argparse
import collections
import contextlib
import errno
import json
import os
import shutil
import subprocess
import sys
import tarfile
import tempfile

from operator import itemgetter
from functools import total_ordering
from typing import Any, Dict, Optional, Sequence, Set, Tuple

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
FUCHSIA_ROOT = os.path.dirname(  # $root
    os.path.dirname(  # scripts
        os.path.dirname(  # sdk
            SCRIPT_DIR)))  # merger
PIGZ_PATH = os.path.join(
    FUCHSIA_ROOT, "prebuilt", "third_party", "pigz", "pigz")

# Reminder about the layout of each SDK directory:
#
# The top-level meta/manifest.json describes the whole SDK content
# as a JSON object, whose 'parts' key is an array of objects with
# with the following schema:
#
#    "meta": [string]: Path to an SDK element metadata file, relative
#                      to the SDK directory.
#
#    "type": [string]: Element type.
#
# A few examples:
#
#    {
#      "meta": "docs/low_level.json",
#      "type": "documentation"
#    },
#    {
#      "meta": "fidl/fuchsia.accessibility.gesture/meta.json",
#      "type": "fidl_library"
#    },
#    {
#      "meta": "pkg/vulkan/vulkan.json",
#      "type": "data"
#    },
#
# Then each element metadata JSON file itself is a JSON object whose
# schema depend on its "type" value.
#

# TODO: Use typing.TypeAlias introduced in Python 3.10 when possible.
TypeAlias = Any

# An SdkManifest is just a JSON object implemented as a Python dictionary
# for now. Define an alias for type checking only.
SdkManifest: TypeAlias = Dict[str, Any]

Path: TypeAlias = str


@total_ordering
class Part(object):
    '''Models a 'parts' array entry from an SDK manifest.'''

    def __init__(self, json: Dict):
        self.meta = json['meta']
        self.type = json['type']

    def __lt__(self, other):
        return (self.meta, self.type) < (other.meta, other.type)

    def __eq__(self, other):
        assert isinstance(other, self.__class__)
        return self.meta == other.meta and self.type == other.type

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return hash((self.meta, self.type))


def _ensure_directory(path: Path):
    '''Ensures that the directory hierarchy of the given path exists.'''
    os.makedirs(os.path.dirname(path), exist_ok=True)


class ElementMeta(object):
    '''Models the metadata of a given SDK element.'''

    def __init__(self, meta: Dict[str, Any]):
        self._meta = meta

    @property
    def type(self):
        '''Returns the SDK element type.'''
        if 'schema_id' in self._meta:
            return self._meta['data']['type']
        return self._meta['type']

    @property
    def json(self):
        '''Return the JSON object for this element metadata instance.'''
        return self._meta

    def get_files(self) -> Tuple[Set[Path], Dict[str, Set[Path]]]:
        '''Extracts the files associated with the given element.
        Returns a 2-tuple containing:
         - the set of arch-independent files;
         - the sets of arch-dependent files, indexed by architecture.
        '''
        type = self.type
        common_files = set()
        arch_files = {}
        if type == 'cc_prebuilt_library':
            common_files.update(self._meta['headers'])
            if 'ifs' in self._meta:
                common_files.add(
                    os.path.join(self._meta['root'], self._meta['ifs']))
            for arch, binaries in self._meta['binaries'].items():
                contents = set()
                contents.add(binaries['link'])
                if 'dist' in binaries:
                    contents.add(binaries['dist'])
                if 'debug' in binaries:
                    contents.add(binaries['debug'])
                arch_files[arch] = contents
        elif type == 'cc_source_library':
            common_files.update(self._meta['headers'])
            common_files.update(self._meta['sources'])
        elif type == 'dart_library':
            common_files.update(self._meta['sources'])
        elif type == 'ffx_tool':
            if 'files' in self._meta:
                for (name, collection) in self._meta["files"].items():
                    if name == "executable" or name == "executable_metadata":
                        common_files.add(collection)
                    else:
                        common_files.update(collection)
            if 'target_files' in self._meta:
                for (arch, binaries) in self._meta["target_files"].items():
                    arch_files[arch] = set()
                    for (name, collection) in binaries.items():
                        if name == "executable" or name == "executable_metadata":
                            arch_files[arch].add(collection)
                        else:
                            arch_files[arch].update(collection)
        elif type == 'fidl_library':
            common_files.update(self._meta['sources'])
        elif type in ['host_tool', 'companion_host_tool', 'package']:
            if 'files' in self._meta:
                common_files.update(self._meta['files'])
            if 'target_files' in self._meta:
                arch_files.update(self._meta['target_files'])
        elif type == 'loadable_module':
            common_files.update(self._meta['resources'])
            arch_files.update(self._meta['binaries'])
        elif type == 'sysroot':
            for ifs_file in self._meta['ifs_files']:
                common_files.add(os.path.join("pkg", "sysroot", ifs_file))
            for arch, version in self._meta['versions'].items():
                contents = set()
                contents.update(version['headers'])
                contents.update(version['link_libs'])
                contents.update(version['dist_libs'])
                contents.update(version['debug_libs'])
                arch_files[arch] = contents
        elif type == 'documentation':
            common_files.update(self._meta['docs'])
        elif type in ('config', 'license', 'component_manifest'):
            common_files.update(self._meta['data'])
        elif type in ('version_history'):
            # These types are pure metadata.
            pass
        elif type == 'bind_library':
            common_files.update(self._meta['sources'])
        else:
            raise Exception('Unknown element type: ' + type)

        return (common_files, arch_files)

    def merge_with(self, other: ElementMeta) -> ElementMeta:
        '''Merge current instance with another one and return new value.'''
        meta_one = self._meta
        meta_two = other._meta

        # TODO(fxbug.dev/5362): verify that the common parts of the metadata files are in
        # fact identical.
        type = self.type
        if type != other.type:
            raise Exception(
                'Incompatible element types (%s vs %s)' % (type, other.type))

        meta = {}
        if type in ('cc_prebuilt_library', 'loadable_module'):
            meta = meta_one
            meta['binaries'].update(meta_two['binaries'])
        elif type == 'package':
            meta = meta_one
            meta['package_manifests'] += meta_two['package_manifests']
            # Remove duplicate items, and sort final result.
            meta['package_manifests'] = sorted(
                [
                    dict(t) for t in
                    {tuple(d.items()) for d in meta['package_manifests']}
                ],
                key=itemgetter(
                    'api_level', 'target_architecture', 'manifest_file'))
            meta['target_files'].update(meta_two['target_files'])
        elif type == 'sysroot':
            meta = meta_one
            meta['versions'].update(meta_two['versions'])
        elif type in ['ffx_tool', 'host_tool', 'companion_host_tool']:
            meta = meta_one
            if not 'target_files' in meta:
                meta['target_files'] = {}
            if 'target_files' in meta_two:
                meta['target_files'].update(meta_two['target_files'])
        elif type in ('cc_source_library', 'dart_library', 'fidl_library',
                      'documentation', 'device_profile', 'config', 'license',
                      'component_manifest', 'bind_library', 'version_history'):
            # These elements are arch-independent, the metadata does not need any
            # update.
            meta = meta_one
        else:
            raise Exception('Unknown element type: ' + type)

        return ElementMeta(meta)


def _has_host_content(parts: Set[Part]):
    '''Returns true if the given list of SDK parts contains an element with
    content built for a host.
    '''
    return 'host_tool' in [part.type for part in parts]


def _merge_sdk_manifests(manifest_one: SdkManifest,
                         manifest_two: SdkManifest) -> Optional[SdkManifest]:
    """Merge two SDK manifests into one. Returns None in case of error."""
    parts_one = set([Part(p) for p in manifest_one['parts']])
    parts_two = set([Part(p) for p in manifest_two['parts']])

    manifest: SdkManifest = {'arch': {}}

    # Schema version.
    if manifest_one['schema_version'] != manifest_two['schema_version']:
        print('Error: mismatching schema version')
        return None
    manifest['schema_version'] = manifest_one['schema_version']

    # Host architecture.
    host_archs = set()
    if _has_host_content(parts_one):
        host_archs.add(manifest_one['arch']['host'])
    if _has_host_content(parts_two):
        host_archs.add(manifest_two['arch']['host'])
    if not host_archs:
        # The archives do not have any host content. The architecture is not
        # meaningful in that case but is still needed: just pick one.
        host_archs.add(manifest_one['arch']['host'])
    if len(host_archs) != 1:
        print(
            'Error: mismatching host architecture: %s' % ', '.join(host_archs))
        return None
    manifest['arch']['host'] = list(host_archs)[0]

    def compare_then_copy(name: str) -> bool:
        """Copy the value of a manifest field after checking for correctness."""
        value1 = manifest_one[name]
        value2 = manifest_two[name]
        if value1 != value2:
            print(f'Error: mismatching {name}: \'{value1}\' vs \'{value2}\'')
            return False

        manifest[name] = value1
        return True

    # Id.
    if not compare_then_copy('id'):
        return None

    # Root.
    if not compare_then_copy('root'):
        return None

    # Target architectures.
    manifest['arch']['target'] = sorted(
        set(manifest_one['arch']['target']) |
        set(manifest_two['arch']['target']))

    # Parts.
    manifest['parts'] = [vars(p) for p in sorted(parts_one | parts_two)]
    return manifest


def tarfile_writer(
        archive_file: Path, source_dir: Path, compressed: bool = True):
    """Write an archive using the Python tarfile module."""
    all_files: List[Tuple[str, str]] = []
    for root, dirs, files in os.walk(source_dir):
        for f in files:
            src_path = os.path.join(root, f)
            dst_path = os.path.relpath(src_path, source_dir)
            all_files.append((dst_path, src_path))
    all_files = sorted(all_files)

    options = "w:gz" if compressed else "w"
    with tarfile.open(archive_file, options) as archive:
        for dst_path, src_path in all_files:
            info = tarfile.TarInfo(dst_path)
            s = os.stat(src_path)
            info.size = s.st_size
            info.mode = s.st_mode
            # Leave all other fields as default for
            # deterministic output. uid/gid will be 0.
            # mtime will be 0 too (January 1st 1970), and type will be
            # tarfile.REGTYPE which is fine since directories or symlinks
            # are never stored in the archive.
            with open(src_path, 'rb') as f:
                archive.addfile(info, f)


def pigz_writer(archive_file: Path, source_dir: Path):
    """Write an uncompressed archive using the Python tarfile module,
    then compress with pigz."""
    temp_archive = archive_file + ".tmp.tar"
    tarfile_writer(temp_archive, source_dir, compressed=False)
    # Invoke pigz with its default block size of 128 KiB
    # The -n option avoids writing the name of the input archive into the result.
    # The -9 option enables max compression.
    subprocess.check_call([PIGZ_PATH, "-n", "-9", temp_archive])
    os.rename(temp_archive + ".gz", archive_file)


class MergeState(object):
    """Common state for all merge operations. Can be used as a context manager."""

    def __init__(self):
        self._all_outputs: Set[Path] = set()
        self._all_inputs: Set[Path] = set()
        self._temp_dirs: Set[Path] = set()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, exc_tb):
        self._remove_all_temp_dirs()
        return False  # Do not suppress exceptions

    def get_temp_dir(self) -> Path:
        """Return new temporary directory path."""
        temp_dir = tempfile.mkdtemp(prefix='fuchsia-sdk-merger')

        self._temp_dirs.add(temp_dir)
        return temp_dir

    def _remove_all_temp_dirs(self):
        """Remove all temporary directories."""
        for temp_dir in self._temp_dirs:
            shutil.rmtree(temp_dir, ignore_errors=True)

    def is_temp_file(self, path: Path) -> bool:
        """Return true if path is inside one of our temporary directories."""
        assert os.path.isabs(path)
        for tmp_dir in self._temp_dirs:
            if os.path.commonprefix([path, tmp_dir]) == tmp_dir:
                return True
        return False

    def add_output(self, path: Path):
        """Add an output path, ignored if temporary."""
        # For outputs, do not follow symlinks.
        path = os.path.abspath(path)
        if not self.is_temp_file(path):
            self._all_outputs.add(path)

    def add_input(self, path: Path):
        """Add an input path, ignored if temporary."""
        # For inputs, always resolve symlinks since that what matters
        # for Ninja (which never follows symlinks themselves).
        path = os.path.abspath(os.path.realpath(path))
        if not self.is_temp_file(path):
            self._all_inputs.add(path)

    def get_depfile_inputs_and_outputs(
            self) -> Tuple[Sequence[Path], Sequence[Path]]:
        """Return the lists of inputs and outputs that should appear in the depfile."""

        def make_relative_paths(paths):
            return sorted([os.path.relpath(os.path.realpath(p)) for p in paths])

        return make_relative_paths(self._all_inputs), make_relative_paths(
            self._all_outputs)

    def open_archive(self, archive: Path) -> Path:
        """Uncompress an archive and return the path of its temporary extraction directory."""
        extract_dir = self.get_temp_dir()
        with tarfile.open(archive) as archive_file:
            archive_file.extractall(extract_dir)
        return extract_dir

    def write_archive(self, archive: Path, source_dir: Path):
        """Write a compressed archive, using the pigz prebuilt if available"""
        if os.path.isfile(PIGZ_PATH):
            pigz_writer(archive, source_dir)
        else:
            tarfile_writer(archive, source_dir)
        self.add_output(archive)

    def write_json_output(self, path: Path, content: Any, dry_run: bool):
        """Write JSON output file."""
        if not dry_run:
            _ensure_directory(path)
            with open(path, 'w') as f:
                json.dump(
                    content, f, indent=2, sort_keys=True, separators=(',', ':'))
        self.add_output(path)


class InputSdk(object):
    """Models a single input SDK archive or directory during merge operations."""

    def __init__(self, archive: Path, directory: Path, state: MergeState):
        """Initialize instance. Either archive or directory must be set."""
        self._state = state
        if archive:
            assert not directory, 'Cannot set both archive and directory'
            self._directory = state.open_archive(archive)
        else:
            assert directory, 'Either archive or directory must be set'
            self._directory = directory

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, exc_tb):
        # Nothing to do here, extracted archive will be removed by
        # MergeState.__exit__() itself.
        return False

    @property
    def directory(self) -> Path:
        """Return directory path."""
        return self._directory

    def _read_json(self, file: Path) -> Any:
        source = os.path.join(self._directory, file)
        self._state.add_input(source)
        with open(source) as f:
            return json.load(f)

    def get_manifest(self) -> SdkManifest:
        """Return the manifest for this SDK."""
        return self._read_json(os.path.join('meta', 'manifest.json'))

    def get_element_meta(self, element: Path) -> ElementMeta:
        """Return the contents of the given element's manifest."""
        # 'element' is actually a path to a meta.json file, relative
        # to the SDK's top directory.
        return ElementMeta(self._read_json(element))


class OutputSdk(object):
    """Model either an output archive or directory during a merge operation."""

    def __init__(
            self, archive: Path, directory: Path, dry_run: bool,
            state: MergeState):
        """Initialize instance. Either archive or directory must be set."""
        self._dry_run = dry_run
        self._archive = archive
        self._state = state
        if directory:
            # NOTE: If both directory and archive are set, the directory
            # will be populated with symlinks, then the archive will be
            # created from its content in __exit__() below.
            if self._dry_run:
                # Use a temporary directory to keep the destination directory
                # untouched during dry-runs.
                self._directory = state.get_temp_dir()
            else:
                self._directory = directory
        elif archive:
            # If only archive is provided, create a temporary output directory
            # for its content.
            self._directory = state.get_temp_dir()
        else:
            assert False, 'Either archive or directory must be set'

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, exc_tb):
        if exc_type is None and self._archive:
            if self._dry_run:
                self._state.add_output(self._archive)
            else:
                self._state.write_archive(self._archive, self._directory)
        return False  # Do not supress exceptions.

    def write_manifest(self, manifest):
        self._state.write_json_output(
            os.path.join(self._directory, 'meta', 'manifest.json'), manifest,
            self._dry_run)

    def write_element_meta(self, element: Path, element_meta: ElementMeta):
        self._state.write_json_output(
            os.path.join(self._directory, element), element_meta.json,
            self._dry_run)

    def copy_file(self, file, source_dir):
        '''Copies a file to a given sub-path, taking care of creating directories if
       needed.
       '''
        source = os.path.realpath(os.path.join(source_dir, file))
        destination = os.path.join(self._directory, file)
        if not self._dry_run:
            _ensure_directory(destination)

            if os.path.exists(destination):
                os.unlink(destination)

            destination = os.path.realpath(destination)

            # Creating a relative symlink to the source file is sufficient,
            # except in the case where the source path is within a temporary
            # directory (which will be removed before script exit), and the
            # destination is in the final output directory.
            #
            # This can happen because the script creates new files when
            # merging the content of meta.json files, for example consider
            # this case:
            #
            #   # merging input1 and input2 which both have foo/meta.json
            #   input1/foo/meta.json + input2/foo/meta.json
            #     -> tmpdir/foo/meta.json   (a new file)
            #
            #   # merging tmpdir and input3, where input3/foo/meta.json
            #   # does not exist:
            #   tmpdir/foo/meta.json + {}
            #     -> output_dir/foo/meta.json
            #
            # In that last case, a symlink to tmpdir/foo/meta.json would
            # become stale on script exit, so a copy is required instead.
            #
            # Note that source is a real path here, so if it points inside
            # a temporary directory, this means it is a real file from a
            # previous merge operation.
            #
            if self._state.is_temp_file(source) and \
                    not self._state.is_temp_file(destination):
                shutil.copy2(source, destination)
            else:
                target_path = os.path.relpath(
                    source, os.path.dirname(destination))
                os.symlink(target_path, destination)

        self._state.add_input(source)
        self._state.add_output(destination)

    def copy_files(self, files, source_dir):
        for file in files:
            self.copy_file(file, source_dir)

    def copy_identical_files(self, set_one, set_two, source_dir):
        if set_one != set_two:
            return False
        self.copy_files(set_one, source_dir)
        return True

    def copy_element(self, element: Path, source_sdk: InputSdk):
        '''Copy an entire SDK element to a given directory.'''
        meta = source_sdk.get_element_meta(element)
        assert meta is not None, 'Could not find metadata for element: %s, %s, %s' % (
            element, meta, source_sdk)
        common_files, arch_files = meta.get_files()
        files = common_files
        for more_files in arch_files.values():
            files.update(more_files)
        self.copy_files(files, source_sdk.directory)
        # Copy the metadata file as well.
        self.copy_file(element, source_sdk.directory)


def merge_sdks(
        first_sdk: InputSdk, second_sdk: InputSdk,
        output_sdk: OutputSdk) -> bool:
    first_manifest = first_sdk.get_manifest()
    second_manifest = second_sdk.get_manifest()
    first_parts = set([Part(p) for p in first_manifest['parts']])
    second_parts = set([Part(p) for p in second_manifest['parts']])
    common_parts = first_parts & second_parts

    # Copy elements that appear in a single SDK
    for element_part in sorted(first_parts - common_parts):
        output_sdk.copy_element(element_part.meta, first_sdk)
    for element_part in sorted(second_parts - common_parts):
        output_sdk.copy_element(element_part.meta, second_sdk)

    # Verify and merge elements which are common to both SDKs.
    for raw_part in sorted(common_parts):
        element = raw_part.meta
        first_meta = first_sdk.get_element_meta(element)
        second_meta = second_sdk.get_element_meta(element)
        first_common, first_arch = first_meta.get_files()
        second_common, second_arch = second_meta.get_files()

        # Common files should not vary.
        if not output_sdk.copy_identical_files(first_common, second_common,
                                               first_sdk.directory):
            print('Error: different common files for %s' % (element))
            return False

        # Arch-dependent files need to be merged in the metadata.
        all_arches = set(first_arch.keys()) | set(second_arch.keys())
        for arch in all_arches:
            if arch in first_arch and arch in second_arch:
                if not output_sdk.copy_identical_files(first_arch[arch],
                                                       second_arch[arch],
                                                       first_sdk.directory):
                    print('Error: different %s files for %s' % (arch, element))
                    return False
            elif arch in first_arch:
                output_sdk.copy_files(first_arch[arch], first_sdk.directory)
            elif arch in second_arch:
                output_sdk.copy_files(second_arch[arch], second_sdk.directory)

        new_meta = first_meta.merge_with(second_meta)
        output_sdk.write_element_meta(element, new_meta)

    output_manifest = _merge_sdk_manifests(first_manifest, second_manifest)
    if not output_manifest:
        return False

    output_sdk.write_manifest(output_manifest)
    return True


# A pair used to model either an input archive or an input directory.
InputInfo = collections.namedtuple('InputInfo', 'archive directory')


def make_archive_info(archive: Path) -> InputInfo:
    return InputInfo(archive=archive, directory=None)


def make_directory_info(directory: Path) -> InputInfo:
    return InputInfo(archive=None, directory=directory)


class InputAction(argparse.Action):
    """custom sub-class to handle input arguments.

    This works by storing in the 'inputs' namespace attribute a
    list of InputInfo values.
    """

    def __init__(self, option_strings, dest, **kwargs):
        dest = 'inputs'
        super(InputAction, self).__init__(option_strings, dest, **kwargs)

    def __call__(self, parser, namespace, values, option_string=None):
        assert isinstance(
            values, str), "Unsupported add_argument() 'type' value"
        if option_string == '--input-directory':
            input = make_directory_info(values)
        elif option_string == '--input-archive':
            input = make_archive_info(values)
        else:
            assert False, "Unsupported options string %s" % option_string

        inputs = getattr(namespace, self.dest)
        if inputs is None:
            inputs = []
        inputs.append(input)
        setattr(namespace, self.dest, inputs)


def main(main_args=None):
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument(
        '--input-directory',
        help='Path to an input SDK - as a directory',
        metavar='DIR',
        action=InputAction,
    )
    parser.add_argument(
        '--input-archive',
        help='Path to an input SDK -as an archive',
        metavar='ARCHIVE',
        action=InputAction,
    )
    first_group = parser.add_mutually_exclusive_group()
    first_group.add_argument(
        '--first-archive',
        help='Path to the first SDK - as an archive',
        metavar='ARCHIVE1',
        default='')
    first_group.add_argument(
        '--first-directory',
        help='Path to the first SDK - as a directory',
        metavar='DIR1',
        default='')
    second_group = parser.add_mutually_exclusive_group()
    second_group.add_argument(
        '--second-archive',
        help='Path to the second SDK - as an archive',
        metavar='ARCHIVE2',
        default='')
    second_group.add_argument(
        '--second-directory',
        help='Path to the second SDK - as a directory',
        metavar='DIR2',
        default='')
    parser.add_argument(
        '--output-archive',
        help='Path to the merged SDK - as an archive',
        metavar='OUT_ARCHIVE',
        default='')
    parser.add_argument(
        '--output-directory',
        help='Path to the merged SDK - as a directory',
        metavar='OUT_DIR',
        default='')
    parser.add_argument('--stamp-file', help='Path to the stamp file')
    hermetic_group = parser.add_mutually_exclusive_group()
    hermetic_group.add_argument('--depfile', help='Path to the stamp file')
    hermetic_group.add_argument(
        '--hermetic-inputs-file', help='Path to the hermetic inputs file')
    args = parser.parse_args(main_args)

    # Convert --first-xx and --second-xxx options into the equivalent
    # --input-xxx ones.
    if args.first_archive or args.first_directory:
        if args.inputs:
            parser.error(
                'Cannot use --input-xxx option with --first-xxx option!')
            return 1

        if args.first_archive:
            first_input = make_archive_info(args.first_archive)
        else:
            first_input = make_directory_info(args.first_directory)

        if args.second_archive:
            second_input = make_archive_info(args.second_archive)
        elif args.second_directory:
            second_input = make_directory_info(args.second_directory)
        else:
            parser.error('Using --first-xxx requires --second-xxx too!')
            return 1

        args.inputs = [first_input, second_input]

    elif args.second_archive or args.second_directory:
        parser.error('Using --second-xxx requires --first-xxx too!')
        return 1

    if not args.inputs:
        parser.error(
            'At least one of --input-archive or --input directory is required!')

    if not args.output_archive and not args.output_directory:
        parser.error(
            'At least one of --output-archive or --output-directory is required!'
        )

    if len(args.inputs
          ) == 1 and args.inputs[0].archive and args.output_directory:
        parser.error(
            'Using a single input archive as input and an output directory is not supported!\n'
            +
            'as the result would contain dangling symlinks. Just uncompress the archive manually!'
        )

    has_hermetic_inputs_file = bool(args.hermetic_inputs_file)

    has_errors = False

    with MergeState() as state:
        num_inputs = len(args.inputs)
        for n, input in enumerate(args.inputs):
            input_sdk = InputSdk(
                args.inputs[n].archive, args.inputs[n].directory, state)

            if n == 0:
                previous_input_sdk = input_sdk
                if num_inputs > 1:
                    # Just record the first entry, no merge needed.
                    continue

            if n + 1 == num_inputs:
                # The final output directory or archive.
                out_archive = args.output_archive
                out_directory = args.output_directory
                out_dryrun = has_hermetic_inputs_file
            else:
                # This is an intermediate merge operation, use a temporary directory for it.
                out_archive = None
                out_directory = state.get_temp_dir()
                out_dryrun = False
            # Perform the merge operation
            with OutputSdk(out_archive, out_directory, out_dryrun,
                           state) as output_sdk:
                if not merge_sdks(previous_input_sdk, input_sdk, output_sdk):
                    return 1

            # Use intermediate output as the first input for the next operation.
            if n + 1 != num_inputs:
                previous_input_sdk = InputSdk(None, out_directory, state)

        depfile_inputs, depfile_outputs = state.get_depfile_inputs_and_outputs()
        if args.hermetic_inputs_file:
            with open(args.hermetic_inputs_file, 'w') as hermetic_inputs_file:
                hermetic_inputs_file.write('\n'.join(depfile_inputs))

        if args.depfile:
            with open(args.depfile, 'w') as depfile:
                depfile.write(
                    '{}: {}'.format(
                        ' '.join(depfile_outputs), ' '.join(depfile_inputs)))

    if args.stamp_file and not has_hermetic_inputs_file:
        with open(args.stamp_file, 'w') as stamp_file:
            stamp_file.write('')

    return 1 if has_errors else 0


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