#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
# Copyright © 2024 Intel Corporation

from pathlib import Path
import argparse
import concurrent.futures
import os
import subprocess
import sys
import typing as T

from mesonbuild.mesonlib import version_compare

MESONBUILD = 'mesonbuild/'

additional = [
    'run_mypy.py',
    'run_project_tests.py',
    'run_single_test.py',
    'tools',
    'docs/genrefman.py',
    'docs/refman',
    'unittests/helpers.py',
]

def check_mypy() -> None:
    try:
        import mypy
    except ImportError:
        print('Failed import mypy')
        sys.exit(1)
    from mypy.version import __version__ as mypy_version
    if not version_compare(mypy_version, '>=0.812'):
        print('mypy >=0.812 is required, older versions report spurious errors')
        sys.exit(1)

def main() -> int:
    root = Path(__file__).absolute().parent

    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('files', nargs='*')
    parser.add_argument('--mypy', help='path to mypy executable')
    parser.add_argument('-q', '--quiet', action='store_true', help='do not print informational messages')
    parser.add_argument('-p', '--pretty', action='store_true', help='pretty print mypy errors')
    parser.add_argument('-C', '--clear', action='store_true', help='clear the terminal before running mypy')
    parser.add_argument('--allver', action='store_true', help='Check all supported versions of python')

    opts, args = parser.parse_known_args()
    if not opts.mypy:
        check_mypy()

    if opts.pretty:
        args.append('--pretty')

    if opts.clear:
        print('\x1bc', end='', flush=True)

    to_check = [] # type: T.List[str]
    additional_to_check = [] # type: T.List[str]
    if opts.files:
        for f in opts.files:
            if f.startswith(MESONBUILD):
                to_check.append(f)
            elif f in additional:
                additional_to_check.append(f)
            elif any(f.startswith(i) for i in additional):
                additional_to_check.append(f)
            else:
                if not opts.quiet:
                    print(f'skipping {f!r} because it is not yet typed')
    else:
        to_check.append(MESONBUILD)
        additional_to_check.extend(additional)

    if not to_check:
        if not opts.quiet:
            print('nothing to do...')
        return 0

    command = [opts.mypy] if opts.mypy else [sys.executable, '-m', 'mypy']
    if not opts.quiet:
        print('Running mypy (this can take some time) ...')

    if opts.allver:
        versions = ['default'] + [f'3.{minor}' for minor in range(10, sys.version_info[1])]
    else:
        versions = ['default']

    def run_mypy_version(version: str) -> T.Tuple[int, str, str]:
        if version == 'default':
            cmd = command + args + to_check + additional_to_check
        else:
            cmd = command + args + to_check + [f'--python-version={version}']

        env = os.environ.copy()
        if sys.stdout.isatty():
            env['MYPY_FORCE_COLOR'] = "1"

        result = subprocess.run(
            cmd,
            cwd=root,
            capture_output=True,
            text=True,
            env=env
        )

        return (result.returncode, version, result.stdout + result.stderr)

    if not opts.quiet and opts.allver:
        for version in versions:
            print(f'Starting mypy check for python version: {version}')

    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = [executor.submit(run_mypy_version, version) for version in versions]

        retcode = 0
        for future in concurrent.futures.as_completed(futures):
            exit_code, version, output = future.result()

            if not opts.allver:
                print(output, end='')
            else:
                if not opts.quiet:
                    print(f'Results for python version: {version} (exit code: {exit_code})')
                print(output, end='')

            retcode = max(retcode, exit_code)

    return retcode

if __name__ == '__main__':
    sys.exit(main())
