# 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.
"""Mirrors a directory tree to another directory using hard links."""

import argparse
import os
from pathlib import Path
from typing import Iterable, Iterator, List


def _parse_args() -> argparse.Namespace:
    """Registers the script's arguments on an argument parser."""

    parser = argparse.ArgumentParser(description=__doc__)

    parser.add_argument('--source-root',
                        type=Path,
                        required=True,
                        help='Prefix to strip from the source files')
    parser.add_argument('sources',
                        type=Path,
                        nargs='*',
                        help='Files to mirror to the directory')
    parser.add_argument('--directory',
                        type=Path,
                        required=True,
                        help='Directory to which to mirror the sources')
    parser.add_argument('--path-file',
                        type=Path,
                        help='File with paths to files to mirror')

    return parser.parse_args()


def _link_files(source_root: Path, sources: Iterable[Path],
                directory: Path) -> Iterator[Path]:
    for source in sources:
        dest = directory / source.relative_to(source_root)
        dest.parent.mkdir(parents=True, exist_ok=True)

        if dest.exists():
            dest.unlink()

        # Use a hard link to avoid unnecessary copies. Resolve the source before
        # linking in case it is a symlink.
        os.link(source.resolve(), dest)

        yield dest


def _link_files_or_dirs(paths: Iterable[Path],
                        directory: Path) -> Iterator[Path]:
    """Links files or directories into the output directory.

    Files are linked directly; files in directories are linked as relative paths
    from the directory.
    """

    for path in paths:
        if path.is_dir():
            files = (p for p in path.glob('**/*') if p.is_file())
            yield from _link_files(path, files, directory)
        elif path.is_file():
            yield from _link_files(path.parent, [path], directory)
        else:
            raise FileNotFoundError(f'{path} does not exist!')


def mirror_paths(source_root: Path,
                 sources: Iterable[Path],
                 directory: Path,
                 path_file: Path = None) -> List[Path]:
    """Creates hard links in the provided directory for the provided sources.

    Args:
      source_root: Base path for files in sources.
      sources: Files to link to from the directory.
      directory: The output directory.
      path_file: A file with file or directory paths to link to.
    """
    directory.mkdir(parents=True, exist_ok=True)

    outputs = list(_link_files(source_root, sources, directory))

    if path_file:
        paths = (Path(p).resolve() for p in path_file.read_text().splitlines())
        outputs.extend(_link_files_or_dirs(paths, directory))

    return outputs


if __name__ == '__main__':
    mirror_paths(**vars(_parse_args()))
