# Copyright 2018 The Meson development team

# 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

#     http://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.
from __future__ import annotations

import itertools
import fnmatch
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor

from ..compilers import lang_suffixes
from ..mesonlib import quiet_git
import typing as T

if T.TYPE_CHECKING:
    import subprocess

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 run_tool(name: str, srcdir: Path, builddir: Path, fn: T.Callable[..., subprocess.CompletedProcess], *args: T.Any) -> int:
    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}
    futures = []
    returncode = 0
    with ThreadPoolExecutor() as e:
        for f in itertools.chain(*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
            futures.append(e.submit(fn, f, *args))
        if futures:
            returncode = max(x.result().returncode for x in futures)
    return returncode
