# SPDX-License-Identifier: Apache-2.0
# Copyright 2013-2016 The Meson development team

from __future__ import annotations

import os
import sys
import argparse
import pickle
import subprocess
import typing as T
import locale

from ..utils.core import ExecutableSerialisation

def buildparser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(description='Custom executable wrapper for Meson. Do not run on your own, mmm\'kay?')
    parser.add_argument('--unpickle')
    parser.add_argument('--capture')
    parser.add_argument('--feed')
    return parser

def run_exe(exe: ExecutableSerialisation, extra_env: T.Optional[T.Dict[str, str]] = None) -> int:
    if exe.exe_wrapper:
        if not exe.exe_wrapper.found():
            raise AssertionError('BUG: Can\'t run cross-compiled exe {!r} with not-found '
                                 'wrapper {!r}'.format(exe.cmd_args[0], exe.exe_wrapper.get_path()))
        cmd_args = exe.exe_wrapper.get_command() + exe.cmd_args
    else:
        cmd_args = exe.cmd_args
    child_env = os.environ.copy()
    if extra_env:
        child_env.update(extra_env)
    if exe.env:
        child_env = exe.env.get_env(child_env)
    if exe.extra_paths:
        child_env['PATH'] = (os.pathsep.join(exe.extra_paths + ['']) +
                             child_env['PATH'])
        if exe.exe_wrapper and any('wine' in i for i in exe.exe_wrapper.get_command()):
            from .. import mesonlib
            child_env['WINEPATH'] = mesonlib.get_wine_shortpath(
                exe.exe_wrapper.get_command(),
                ['Z:' + p for p in exe.extra_paths] + child_env.get('WINEPATH', '').split(';'),
                exe.workdir
            )

    stdin = None
    if exe.feed:
        stdin = open(exe.feed, 'rb')

    pipe = subprocess.PIPE
    if exe.verbose:
        assert not exe.capture, 'Cannot capture and print to console at the same time'
        pipe = None

    p = subprocess.Popen(cmd_args, env=child_env, cwd=exe.workdir,
                         close_fds=False, stdin=stdin, stdout=pipe, stderr=pipe)
    stdout, stderr = p.communicate()

    if stdin is not None:
        stdin.close()

    if p.returncode == 0xc0000135:
        # STATUS_DLL_NOT_FOUND on Windows indicating a common problem that is otherwise hard to diagnose
        strerror = 'Failed to run due to missing DLLs, with path: ' + child_env['PATH']
        raise FileNotFoundError(p.returncode, strerror, cmd_args)

    if p.returncode != 0:
        if exe.pickled:
            print(f'while executing {cmd_args!r}')
        if exe.verbose:
            return p.returncode
        encoding = locale.getpreferredencoding()
        if not exe.capture:
            print('--- stdout ---')
            print(stdout.decode(encoding=encoding, errors='replace'))
        print('--- stderr ---')
        print(stderr.decode(encoding=encoding, errors='replace'))
        return p.returncode
    elif stderr: # Allow a wrapped subprocess to gracefully communicate warnings
        encoding = locale.getpreferredencoding()
        print(stderr.decode(encoding=encoding, errors='replace'))

    if exe.capture:
        skip_write = False
        try:
            with open(exe.capture, 'rb') as cur:
                skip_write = cur.read() == stdout
        except OSError:
            pass
        if not skip_write:
            with open(exe.capture, 'wb') as output:
                output.write(stdout)

    return 0

def run(args: T.List[str]) -> int:
    parser = buildparser()
    options, cmd_args = parser.parse_known_args(args)
    # argparse supports double dash to separate options and positional arguments,
    # but the user has to remove it manually.
    if cmd_args and cmd_args[0] == '--':
        cmd_args = cmd_args[1:]
    if not options.unpickle and not cmd_args:
        parser.error('either --unpickle or executable and arguments are required')
    if options.unpickle:
        if cmd_args or options.capture or options.feed:
            parser.error('no other arguments can be used with --unpickle')
        with open(options.unpickle, 'rb') as f:
            exe = pickle.load(f)
            exe.pickled = True
    else:
        exe = ExecutableSerialisation(cmd_args, capture=options.capture, feed=options.feed)

    return run_exe(exe)

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