#!/usr/bin/env python3
from __future__ import annotations

import argparse
import subprocess
import shutil
import sys
from pathlib import Path
import typing as T

def run(argsv: T.List[str]) -> int:
    commands = [[]]  # type: T.List[T.List[str]]
    SEPARATOR = ';;;'

    # Generate CMD parameters
    parser = argparse.ArgumentParser(description='Wrapper for add_custom_command')
    parser.add_argument('-d', '--directory', type=str, metavar='D', required=True, help='Working directory to cwd to')
    parser.add_argument('-o', '--outputs', nargs='+', metavar='O', required=True, help='Expected output files')
    parser.add_argument('-O', '--original-outputs', nargs='*', metavar='O', default=[], help='Output files expected by CMake')
    parser.add_argument('commands', nargs=argparse.REMAINDER, help=f'A "{SEPARATOR}" separated list of commands')

    # Parse
    args = parser.parse_args(argsv)
    directory = Path(args.directory)

    dummy_target = None
    if len(args.outputs) == 1 and len(args.original_outputs) == 0:
        dummy_target = Path(args.outputs[0])
    elif len(args.outputs) != len(args.original_outputs):
        print('Length of output list and original output list differ')
        return 1

    for i in args.commands:
        if i == SEPARATOR:
            commands += [[]]
            continue

        i = i.replace('"', '')  # Remove lefover quotes
        commands[-1] += [i]

    # Execute
    for i in commands:
        # Skip empty lists
        if not i:
            continue

        cmd = []
        stdout = None
        stderr = None
        capture_file = ''

        for j in i:
            if j in {'>', '>>'}:
                stdout = subprocess.PIPE
                continue
            elif j in {'&>', '&>>'}:
                stdout = subprocess.PIPE
                stderr = subprocess.STDOUT
                continue

            if stdout is not None or stderr is not None:
                capture_file += j
            else:
                cmd += [j]

        try:
            directory.mkdir(parents=True, exist_ok=True)

            res = subprocess.run(cmd, stdout=stdout, stderr=stderr, cwd=str(directory), check=True)
            if capture_file:
                out_file = directory / capture_file
                out_file.write_bytes(res.stdout)
        except subprocess.CalledProcessError:
            return 1

    if dummy_target:
        dummy_target.touch()
        return 0

    # Copy outputs
    zipped_outputs = zip([Path(x) for x in args.outputs], [Path(x) for x in args.original_outputs])
    for expected, generated in zipped_outputs:
        do_copy = False
        if not expected.exists():
            if not generated.exists():
                print('Unable to find generated file. This can cause the build to fail:')
                print(generated)
                do_copy = False
            else:
                do_copy = True
        elif generated.exists():
            if generated.stat().st_mtime > expected.stat().st_mtime:
                do_copy = True

        if do_copy:
            if expected.exists():
                expected.unlink()
            shutil.copyfile(str(generated), str(expected))

    return 0

if __name__ == '__main__':
    sys.exit(run(sys.argv[1:]))
