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

from __future__ import annotations

import asyncio.subprocess
import fnmatch
import itertools
import json
import signal
import sys
from pathlib import Path

from .. import mlog
from ..compilers import lang_suffixes
from ..mesonlib import quiet_git, join_args, determine_worker_count
from ..mtest import complete_all
import typing as T

Info = T.TypeVar("Info")

async def run_with_buffered_output(cmdlist: T.List[str]) -> int:
    """Run the command in cmdlist, buffering the output so that it is
       not mixed for multiple child processes.  Kill the child on
       cancellation."""
    quoted_cmdline = join_args(cmdlist)
    p: T.Optional[asyncio.subprocess.Process] = None
    try:
        p = await asyncio.create_subprocess_exec(*cmdlist,
                                                 stdin=asyncio.subprocess.DEVNULL,
                                                 stdout=asyncio.subprocess.PIPE,
                                                 stderr=asyncio.subprocess.STDOUT)
        stdo, _ = await p.communicate()
    except FileNotFoundError as e:
        print(mlog.blue('>>>'), quoted_cmdline, file=sys.stderr)
        print(mlog.red('not found:'), e.filename, file=sys.stderr)
        return 1
    except asyncio.CancelledError:
        if p:
            p.kill()
            await p.wait()
            return p.returncode or 1
        else:
            return 0

    if stdo:
        print(mlog.blue('>>>'), quoted_cmdline, flush=True)
        sys.stdout.buffer.write(stdo)
    return p.returncode

async def _run_workers(infos: T.Iterable[Info],
                       fn: T.Callable[[Info], T.Iterable[T.Coroutine[None, None, int]]]) -> int:
    futures: T.List[asyncio.Future[int]] = []
    semaphore = asyncio.Semaphore(determine_worker_count())

    async def run_one(worker_coro: T.Coroutine[None, None, int]) -> int:
        try:
            async with semaphore:
                return await worker_coro
        except asyncio.CancelledError as e:
            worker_coro.throw(e)
            return await worker_coro

    def sigterm_handler() -> None:
        for f in futures:
            f.cancel()

    if sys.platform != 'win32':
        loop = asyncio.get_running_loop()
        loop.add_signal_handler(signal.SIGINT, sigterm_handler)
        loop.add_signal_handler(signal.SIGTERM, sigterm_handler)

    for i in infos:
        futures.extend((asyncio.ensure_future(run_one(x)) for x in fn(i)))
    if not futures:
        return 0

    try:
        await complete_all(futures)
    except BaseException:
        for f in futures:
            f.cancel()
        raise

    return max(f.result() for f in futures if f.done() and not f.cancelled())

def parse_pattern_file(fname: Path) -> T.List[str]:
    patterns = []
    try:
        with fname.open(encoding='utf-8') as f:
            for line in f:
                pattern = line.strip()
                if pattern and not pattern.startswith('#'):
                    patterns.append(pattern)
    except FileNotFoundError:
        pass
    return patterns

def all_clike_files(name: str, srcdir: Path, builddir: Path) -> T.Iterable[Path]:
    patterns = parse_pattern_file(srcdir / f'.{name}-include')
    globs: T.Union[T.List[T.List[Path]], T.List[T.Generator[Path, None, None]]]
    if patterns:
        globs = [srcdir.glob(p) for p in patterns]
    else:
        r, o = quiet_git(['ls-files'], srcdir)
        if r:
            globs = [[Path(srcdir, f) for f in o.splitlines()]]
        else:
            globs = [srcdir.glob('**/*')]
    patterns = parse_pattern_file(srcdir / f'.{name}-ignore')
    ignore = [str(builddir / '*')]
    ignore.extend([str(srcdir / p) for p in patterns])
    suffixes = set(lang_suffixes['c']).union(set(lang_suffixes['cpp']))
    suffixes.add('h')
    suffixes = {f'.{s}' for s in suffixes}
    for f in itertools.chain.from_iterable(globs):
        strf = str(f)
        if f.is_dir() or f.suffix not in suffixes or \
                any(fnmatch.fnmatch(strf, i) for i in ignore):
            continue
        yield f

def run_clang_tool(name: str, srcdir: Path, builddir: Path, fn: T.Callable[..., T.Coroutine[None, None, int]], *args: T.Any) -> int:
    if sys.platform == 'win32':
        asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())

    def wrapper(path: Path) -> T.Iterable[T.Coroutine[None, None, int]]:
        yield fn(path, *args)
    return asyncio.run(_run_workers(all_clike_files(name, srcdir, builddir), wrapper))

def run_tool_on_targets(fn: T.Callable[[T.Dict[str, T.Any]],
                                       T.Iterable[T.Coroutine[None, None, int]]]) -> int:
    if sys.platform == 'win32':
        asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())

    with open('meson-info/intro-targets.json', encoding='utf-8') as fp:
        targets = json.load(fp)
    return asyncio.run(_run_workers(targets, fn))
