#!/usr/bin/env python

from __future__ import print_function

import argparse
import filecmp
import os
import os.path
import shutil

from swift_build_support.swift_build_support import shell


def merge_file_lists(src_root_dirs, skip_files, skip_subpaths):
    """Merges the file lists recursively from all src_root_dirs supplied,
    returning the union of all file paths found.
    Files matching skip_files are ignored and skipped.
    Subpaths matching skip_subpaths are not recursed into.
    """
    file_list = []
    for src_root_dir in src_root_dirs:
        for src_dir, dirs, files in os.walk(src_root_dir):
            rel_dir = os.path.relpath(src_dir, src_root_dir)
            rel_files = [
                os.path.join(rel_dir, file) for file in files + dirs
                if file not in skip_files]
            file_list.extend(
                filter(lambda file: file not in file_list, rel_files))
            dirs[:] = filter(
                lambda dir: os.path.join(rel_dir, dir)
                not in skip_subpaths, dirs)
    return file_list


def merge_lipo_files(src_root_dirs, file_list, copy_verbatim_subpaths,
                     dest_root_dir, verbose=False, lipo_executable="lipo"):
    """Recursively merges and runs lipo on all files from file_list in
    src_root_dirs to destRoorDir.

    Any path in file_list that's a regular file or symlink is copied or lipo'ed
    into the corresponding location in dest_root_dir. If the file is unique or
    identical in all src_root_dirs, it's copied verbatim. If it's different,
    it's lipo'ed together from all src_root_dirs into a fat binary.

    Any path in file_list that's a directory in src_root_dirs results in a
    corresponding subdirectory in dest_root_dir. If the subdirectory path
    matches copy_verbatim_subpaths, the whole subdirectory is recursively
    copied verbatim.
    """
    lipo_cmd = [lipo_executable, "-create"]

    for file in file_list:
        file_paths = [
            os.path.join(dir, file) for dir in src_root_dirs
            if os.path.exists(os.path.join(dir, file))]
        if len(file_paths) == 0:
            print("-- Warning: Can't locate source file %s" % file)
            continue

        dest_path = os.path.join(
            dest_root_dir, os.path.relpath(file_paths[0], src_root_dirs[0]))

        if all([os.path.islink(item) for item in file_paths]):
            # It's a symlink in all found instances, copy the link.
            print("-- Creating symlink %s" % dest_path)
            # Remove symlink if it already exists
            if os.path.islink(dest_path):
                os.remove(dest_path)
            os.symlink(os.readlink(file_paths[0]), dest_path)
        elif all([os.path.isdir(item) for item in file_paths]):
            # It's a subdir in all found instances.
            # See if we should copy verbatim or create the destination subdir.
            if file in copy_verbatim_subpaths:
                print("-- Copying subdir verbatim %s" % dest_path)
                if os.path.isdir(dest_path):
                    shutil.rmtree(dest_path)
                shutil.copytree(file_paths[0], dest_path, symlinks=True)
            else:
                print("-- Creating subdir %s" % dest_path)
                if not os.path.isdir(dest_path):
                    os.makedirs(dest_path)
        elif all([os.path.isfile(item) for item in file_paths]):
            # It's a regular file in all found instances, see if they're
            # identical.
            if all([filecmp.cmp(item, file_paths[0]) for item in file_paths]):
                # All instances are identical, just copy the unique file.
                print("-- Copying file %s" % dest_path)
                shutil.copy2(file_paths[0], dest_path)
            elif all([os.access(item, os.X_OK) for item in file_paths]):
                # Multiple instances are different and executable, try lipo.
                if verbose:
                    print("-- Running lipo %s to %s" % (file_paths, dest_path))
                else:
                    print("-- Running lipo %s" % dest_path)
                shell.call(lipo_cmd + ["-output", dest_path] + file_paths,
                           echo=verbose)
            else:
                # Multiple instances are different, and they're not executable.
                print(
                    "-- Warning: non-executable source files are different, " +
                    "skipping: %s" % file_paths)
        else:
            print("-- Warning: Unsupport file type, skipping: %s" % file_paths)


def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="""
This script merges and applies 'lipo' to directories. For each file present in
any source directory, it will create a file in the destination directory.

If all the copies of the file in the source directories are the same,
the file is copied directly to the destination. If there are different
files in different directories, but the files are executable,
lipo is run to merge the files together. Otherwise, a warning is produced.

Use --copy-subdirs to override normal logic and copy certain sub directory
paths verbatim. This is useful if some subdirectories already contain fat
binaries.
""")

    parser.add_argument("-v", "--verbose", action='store_true',
                        help="Verbose output and logging")
    parser.add_argument("--lipo", metavar="<path-to-lipo>",
                        default="lipo",
                        help="Path to lipo executable, default is \"lipo\"")
    parser.add_argument("--skip-files", metavar="<skip-files>",
                        default=".DS_Store",
                        help="Files to ignore and skip merge/copy, default " +
                             "is \".DS_Store\"")
    parser.add_argument("--copy-subdirs", metavar="<subdirs-to-copy-verbatim>",
                        default="",
                        help="Optional list of subdirectory paths that " +
                             "should be copied verbatim")

    required_group = parser.add_argument_group("required arguments")
    required_group.add_argument("--destination", metavar="<dest-path>",
                                required=True,
                                help="The merge destination directory")
    required_group.add_argument("src_root_dirs", metavar="<src-path>",
                                nargs='+',
                                help="The source directories to merge-lipo")

    args = parser.parse_args()

    skip_files = args.skip_files.split()
    copy_verbatim_subpaths = [
        subdir.strip('/') for subdir in args.copy_subdirs.split()]

    file_list = merge_file_lists(args.src_root_dirs, skip_files,
                                 copy_verbatim_subpaths)

    if args.verbose:
        print("Discovered files and dirs: %s" % file_list)

    merge_lipo_files(
        args.src_root_dirs, file_list, copy_verbatim_subpaths,
        args.destination, args.verbose, args.lipo)

    return 0


if __name__ == '__main__':
    main()
