#!/usr/bin/env python3

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

from mesonbuild.mesonlib import version_compare

modules = [
    # fully typed submodules
    # 'mesonbuild/ast/',
    'mesonbuild/cargo/',
    'mesonbuild/cmake/',
    'mesonbuild/compilers/',
    'mesonbuild/dependencies/',
    'mesonbuild/interpreter/primitives/',
    'mesonbuild/interpreterbase/',
    'mesonbuild/linkers/',
    'mesonbuild/scripts/',
    'mesonbuild/templates/',
    'mesonbuild/wrap/',

    # specific files
    'mesonbuild/arglist.py',
    'mesonbuild/backend/backends.py',
    # 'mesonbuild/coredata.py',
    'mesonbuild/depfile.py',
    'mesonbuild/envconfig.py',
    'mesonbuild/interpreter/compiler.py',
    'mesonbuild/interpreter/mesonmain.py',
    'mesonbuild/interpreter/interpreterobjects.py',
    'mesonbuild/interpreter/type_checking.py',
    'mesonbuild/mcompile.py',
    'mesonbuild/mdevenv.py',
    'mesonbuild/utils/core.py',
    'mesonbuild/utils/platform.py',
    'mesonbuild/utils/universal.py',
    'mesonbuild/mconf.py',
    'mesonbuild/mdist.py',
    'mesonbuild/minit.py',
    'mesonbuild/minstall.py',
    'mesonbuild/mintro.py',
    'mesonbuild/mlog.py',
    'mesonbuild/msubprojects.py',
    'mesonbuild/modules/__init__.py',
    'mesonbuild/modules/external_project.py',
    'mesonbuild/modules/fs.py',
    'mesonbuild/modules/gnome.py',
    'mesonbuild/modules/i18n.py',
    'mesonbuild/modules/icestorm.py',
    'mesonbuild/modules/java.py',
    'mesonbuild/modules/keyval.py',
    'mesonbuild/modules/modtest.py',
    'mesonbuild/modules/pkgconfig.py',
    'mesonbuild/modules/qt.py',
    'mesonbuild/modules/qt4.py',
    'mesonbuild/modules/qt5.py',
    'mesonbuild/modules/qt6.py',
    'mesonbuild/modules/rust.py',
    'mesonbuild/modules/simd.py',
    'mesonbuild/modules/sourceset.py',
    'mesonbuild/modules/wayland.py',
    'mesonbuild/modules/windows.py',
    'mesonbuild/mparser.py',
    'mesonbuild/msetup.py',
    'mesonbuild/mtest.py',
    'mesonbuild/optinterpreter.py',
    'mesonbuild/programs.py',

    'run_mypy.py',
    'run_project_tests.py',
    'run_single_test.py',
    'tools',
    'docs/genrefman.py',
    'docs/refman',
]

if os.name == 'posix':
    modules.append('mesonbuild/utils/posix.py')
elif os.name == 'nt':
    modules.append('mesonbuild/utils/win32.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:
    check_mypy()

    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 opts.pretty:
        args.append('--pretty')

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

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

    if to_check:
        command = [opts.mypy] if opts.mypy else [sys.executable, '-m', 'mypy']
        if not opts.quiet:
            print('Running mypy (this can take some time) ...')
        retcode = subprocess.run(command + args + to_check, cwd=root).returncode
        if opts.allver and retcode == 0:
            for minor in range(7, sys.version_info[1]):
                if not opts.quiet:
                    print(f'Checking mypy with python version: 3.{minor}')
                p = subprocess.run(command + args + to_check + [f'--python-version=3.{minor}'], cwd=root)
                if p.returncode != 0:
                    retcode = p.returncode
        return retcode
    else:
        if not opts.quiet:
            print('nothing to do...')
        return 0

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