#!/usr/bin/env python3

# SPDX-License-Identifer: Apache-2.0
# Copyright 2021 The Meson development team

import argparse
import json
from pathlib import Path
from copy import deepcopy

import typing as T

T_None = type(None)

# Global root object
root: dict

def assert_has_typed_keys(path: str, data: dict, keys: T.Dict[str, T.Any]) -> dict:
    assert set(data.keys()).issuperset(keys.keys()), f'{path}: DIFF: {set(data.keys()).difference(keys.keys())}'
    res = dict()
    for key, val in keys.items():
        cur = data.pop(key)
        assert isinstance(cur, val), f'{path}: type({key}: {cur}) != {val}'
        res[key] = cur
    return res

def validate_base_obj(path: str, name: str, obj: dict) -> None:
    expected: T.Dict[str, T.Any] = {
        'name': str,
        'description': str,
        'since': (str, T_None),
        'deprecated': (str, T_None),
        'notes': list,
        'warnings': list,
    }
    cur = assert_has_typed_keys(f'{path}.{name}', obj, expected)
    assert cur['name'],                                            f'{path}.{name}'
    assert cur['description'],                                     f'{path}.{name}'
    assert cur['name'] == name,                                    f'{path}.{name}'
    assert all(isinstance(x, str) and x for x in cur['notes']),    f'{path}.{name}'
    assert all(isinstance(x, str) and x for x in cur['warnings']), f'{path}.{name}'

def validate_type(path: str, typ: dict) -> None:
    expected: T.Dict[str, T.Any] = {
        'obj': str,
        'holds': list,
    }
    cur = assert_has_typed_keys(path, typ, expected)
    assert not typ, f'{path} has extra keys: {typ.keys()}'
    assert cur['obj'] in root['objects'], path
    for i in cur['holds']:
        validate_type(path, i)

def validate_arg(path: str, name: str, arg: dict) -> None:
    validate_base_obj(path, name, arg)
    expected: T.Dict[str, T.Any] = {
        'type': list,
        'type_str': str,
        'required': bool,
        'default': (str, T_None),
        'min_varargs': (int, T_None),
        'max_varargs': (int, T_None),
    }
    cur = assert_has_typed_keys(f'{path}.{name}', arg, expected)
    assert not arg, f'{path}.{name} has extra keys: {arg.keys()}'
    assert cur['type'], f'{path}.{name}'
    assert cur['type_str'], f'{path}.{name}'
    for i in cur['type']:
        validate_type(f'{path}.{name}', i)
    if cur['min_varargs'] is not None:
        assert cur['min_varargs'] > 0, f'{path}.{name}'
    if cur['max_varargs'] is not None:
        assert cur['max_varargs'] > 0, f'{path}.{name}'

def validate_function(path: str, name: str, func: dict) -> None:
    validate_base_obj(path, name, func)
    expected: T.Dict[str, T.Any] = {
        'returns': list,
        'returns_str': str,
        'example': (str, T_None),
        'posargs': dict,
        'optargs': dict,
        'kwargs': dict,
        'varargs': (dict, T_None),
        'arg_flattening': bool,
    }
    cur = assert_has_typed_keys(f'{path}.{name}', func, expected)
    assert not func, f'{path}.{name} has extra keys: {func.keys()}'
    assert cur['returns'], f'{path}.{name}'
    assert cur['returns_str'], f'{path}.{name}'
    for i in cur['returns']:
        validate_type(f'{path}.{name}', i)
    for k, v in cur['posargs'].items():
        validate_arg(f'{path}.{name}', k, v)
    for k, v in cur['optargs'].items():
        validate_arg(f'{path}.{name}', k, v)
    for k, v in cur['kwargs'].items():
        validate_arg(f'{path}.{name}', k, v)
    if cur['varargs']:
        validate_arg(f'{path}.{name}', cur['varargs']['name'], cur['varargs'])

def validate_object(path: str, name: str, obj: dict) -> None:
    validate_base_obj(path, name, obj)
    expected: T.Dict[str, T.Any] = {
        'example': (str, T_None),
        'object_type': str,
        'methods': dict,
        'is_container': bool,
        'extends': (str, T_None),
        'returned_by': list,
        'extended_by': list,
        'defined_by_module': (str, T_None),
    }
    cur = assert_has_typed_keys(f'{path}.{name}', obj, expected)
    assert not obj, f'{path}.{name} has extra keys: {obj.keys()}'
    for key, val in cur['methods'].items():
        validate_function(f'{path}.{name}', key, val)
    if cur['extends'] is not None:
        assert cur['extends'] in root['objects'], f'{path}.{name}'
    assert all(isinstance(x, str) for x in cur['returned_by']), f'{path}.{name}'
    assert all(isinstance(x, str) for x in cur['extended_by']), f'{path}.{name}'
    assert all(x in root['objects'] for x in cur['extended_by']), f'{path}.{name}'
    if cur['defined_by_module'] is not None:
        assert cur['defined_by_module'] in root['objects'], f'{path}.{name}'
        assert cur['object_type'] == 'RETURNED', f'{path}.{name}'
        assert root['objects'][cur['defined_by_module']]['object_type'] == 'MODULE', f'{path}.{name}'
        assert name in root['objects_by_type']['modules'][cur['defined_by_module']], f'{path}.{name}'
        return
    assert cur['object_type'] in {'ELEMENTARY', 'BUILTIN', 'MODULE', 'RETURNED'}, f'{path}.{name}'
    if cur['object_type'] == 'ELEMENTARY':
        assert name in root['objects_by_type']['elementary'], f'{path}.{name}'
    if cur['object_type'] == 'BUILTIN':
        assert name in root['objects_by_type']['builtins'], f'{path}.{name}'
    if cur['object_type'] == 'RETURNED':
        assert name in root['objects_by_type']['returned'], f'{path}.{name}'
    if cur['object_type'] == 'MODULE':
        assert name in root['objects_by_type']['modules'], f'{path}.{name}'

def main() -> int:
    global root

    parser = argparse.ArgumentParser(description='Meson JSON docs validator')
    parser.add_argument('doc_file', type=Path, help='The JSON docs to validate')
    args = parser.parse_args()

    root_tmp = json.loads(args.doc_file.read_text(encoding='utf-8'))
    root = deepcopy(root_tmp)
    assert isinstance(root, dict)

    expected: T.Dict[str, T.Any] = {
        'version_major': int,
        'version_minor': int,
        'meson_version': str,
        'functions': dict,
        'objects': dict,
        'objects_by_type': dict,
    }
    cur = assert_has_typed_keys('root', root_tmp, expected)
    assert not root_tmp, f'root has extra keys: {root_tmp.keys()}'

    refs = cur['objects_by_type']
    expected = {
        'elementary': list,
        'builtins': list,
        'returned': list,
        'modules': dict,
    }
    assert_has_typed_keys(f'root.objects_by_type', refs, expected)
    assert not refs, f'root.objects_by_type has extra keys: {refs.keys()}'
    assert all(isinstance(x, str) for x in root['objects_by_type']['elementary'])
    assert all(isinstance(x, str) for x in root['objects_by_type']['builtins'])
    assert all(isinstance(x, str) for x in root['objects_by_type']['returned'])
    assert all(isinstance(x, str) for x in root['objects_by_type']['modules'])
    assert all(x in root['objects'] for x in root['objects_by_type']['elementary'])
    assert all(x in root['objects'] for x in root['objects_by_type']['builtins'])
    assert all(x in root['objects'] for x in root['objects_by_type']['returned'])
    assert all(x in root['objects'] for x in root['objects_by_type']['modules'])
    assert all(root['objects'][x]['object_type'] == 'ELEMENTARY' for x in root['objects_by_type']['elementary'])
    assert all(root['objects'][x]['object_type'] == 'BUILTIN'    for x in root['objects_by_type']['builtins'])
    assert all(root['objects'][x]['object_type'] == 'RETURNED'   for x in root['objects_by_type']['returned'])
    assert all(root['objects'][x]['object_type'] == 'MODULE'     for x in root['objects_by_type']['modules'])

    # Check that module references are correct
    assert all(all(isinstance(x, str)                           for x in v) for k, v in root['objects_by_type']['modules'].items())
    assert all(all(x in root['objects']                         for x in v) for k, v in root['objects_by_type']['modules'].items())
    assert all(all(root['objects'][x]['defined_by_module'] == k for x in v) for k, v in root['objects_by_type']['modules'].items())

    for key, val in cur['functions'].items():
        validate_function('root', key, val)
    for key, val in cur['objects'].items():
        validate_object('root', key, val)

    return 0

if __name__ == '__main__':
    raise SystemExit(main())
