# Copyright 2021 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 .loaderbase import LoaderBase
from .model import (
    Type,
    PosArg,
    VarArgs,
    Kwarg,
    Function,
    Method,
    ObjectType,
    Object,
    ReferenceManual,
)

from mesonbuild import mlog
from mesonbuild import mesonlib

from pathlib import Path
import typing as T

class Template:
    d_feature_check: T.Dict[str, T.Any] = {}
    s_posarg: T.Dict[str, T.Any] = {}
    s_varargs: T.Dict[str, T.Any] = {}
    s_kwarg: T.Dict[str, T.Any] = {}
    s_function: T.Dict[str, T.Any] = {}
    s_object: T.Dict[str, T.Any] = {}

class StrictTemplate(Template):
    def __init__(self) -> None:
        from strictyaml import Map, MapPattern, Optional, Str, Seq, Int, Bool, EmptyList, OrValidator

        d_named_object = {
            'name': Str(),
            'description': Str(),
        }

        d_feture_check = {
            Optional('since', default=''): Str(),
            Optional('deprecated', default=''): Str(),
        }

        self.s_posarg = Map({
            **d_feture_check,
            'description': Str(),
            'type': Str(),
            Optional('default', default=''): Str(),
        })

        self.s_varargs = Map({
            **d_named_object, **d_feture_check,
            'type': Str(),
            Optional('min_varargs', default=-1): Int(),
            Optional('max_varargs', default=-1): Int(),
        })

        self.s_kwarg = Map({
            **d_feture_check,
            'type': Str(),
            'description': Str(),
            Optional('required', default=False): Bool(),
            Optional('default', default=''): Str(),
        })

        self.s_function = Map({
            **d_named_object, **d_feture_check,
            'returns': Str(),
            Optional('notes', default=[]): OrValidator(Seq(Str()), EmptyList()),
            Optional('warnings', default=[]): OrValidator(Seq(Str()), EmptyList()),
            Optional('example', default=''): Str(),
            Optional('posargs'): MapPattern(Str(), self.s_posarg),
            Optional('optargs'): MapPattern(Str(), self.s_posarg),
            Optional('varargs'): self.s_varargs,
            Optional('posargs_inherit', default=''): Str(),
            Optional('optargs_inherit', default=''): Str(),
            Optional('varargs_inherit', default=''): Str(),
            Optional('kwargs'): MapPattern(Str(), self.s_kwarg),
            Optional('kwargs_inherit', default=[]): OrValidator(OrValidator(Seq(Str()), EmptyList()), Str()),
        })

        self.s_object = Map({
            **d_named_object, **d_feture_check,
            'long_name': Str(),
            Optional('extends', default=''): Str(),
            Optional('notes', default=[]): OrValidator(Seq(Str()), EmptyList()),
            Optional('warnings', default=[]): OrValidator(Seq(Str()), EmptyList()),
            Optional('example', default=''): Str(),
            Optional('methods'): Seq(self.s_function),
            Optional('is_container', default=False): Bool()
        })

class FastTemplate(Template):
    d_feature_check: T.Dict[str, T.Any] = {
        'since': '',
        'deprecated': '',
    }

    s_posarg = {
        **d_feature_check,
        'default': '',
    }

    s_varargs: T.Dict[str, T.Any] = {
        **d_feature_check,
        'min_varargs': -1,
        'max_varargs': -1,
    }

    s_kwarg = {
        **d_feature_check,
        'required': False,
        'default': '',
    }

    s_function = {
        **d_feature_check,
        'notes': [],
        'warnings': [],
        'example': '',
        'posargs': {},
        'optargs': {},
        'varargs': None,
        'posargs_inherit': '',
        'optargs_inherit': '',
        'varargs_inherit': '',
        'kwargs': {},
        'kwargs_inherit': [],
    }

    s_object = {
        **d_feature_check,
        'extends': '',
        'notes': [],
        'warnings': [],
        'example': '',
        'methods': [],
        'is_container': False,
    }

class LoaderYAML(LoaderBase):
    def __init__(self, yaml_dir: Path, strict: bool=True) -> None:
        super().__init__()
        self.yaml_dir = yaml_dir
        self.func_dir = self.yaml_dir / 'functions'
        self.elem_dir = self.yaml_dir / 'elementary'
        self.objs_dir = self.yaml_dir / 'objects'
        self.builtin_dir = self.yaml_dir / 'builtins'
        self.modules_dir = self.yaml_dir / 'modules'
        self.strict = strict

        template: Template
        if self.strict:
            import strictyaml
            def loader(file: str, template: T.Any, label: str) -> T.Dict:
                r: T.Dict = strictyaml.load(file, template, label=label).data
                return r

            self._load = loader
            template = StrictTemplate()
        else:
            import yaml
            from yaml import CLoader
            def loader(file: str, template: T.Any, label: str) -> T.Dict:
                return {**template, **yaml.load(file, Loader=CLoader)}

            self._load = loader
            template = FastTemplate()

        self.template = template

    def _fix_default(self, v: T.Dict) -> None:
        if v["default"] is False:
            v["default"] = "false"
        elif v["default"] is True:
            v["default"] = "true"
        else:
            v["default"] = str(v["default"])

    def _process_function_base(self, raw: T.Dict, obj: T.Optional[Object] = None) -> Function:
        # Handle arguments
        posargs = raw.pop('posargs', {})
        optargs = raw.pop('optargs', {})
        varargs = raw.pop('varargs', None)
        kwargs = raw.pop('kwargs', {})

        # Fix kwargs_inherit
        if isinstance(raw['kwargs_inherit'], str):
            raw['kwargs_inherit'] = [raw['kwargs_inherit']]

        # Parse args
        posargs_mapped: T.List[PosArg] = []
        optargs_mapped: T.List[PosArg] = []
        varargs_mapped: T.Optional[VarArgs] = None
        kwargs_mapped: T.Dict[str, Kwarg] = {}

        for k, v in posargs.items():
            if not self.strict:
                v = {**self.template.s_posarg, **v}
                self._fix_default(v)
            v['type'] = Type(v['type'])
            posargs_mapped += [PosArg(name=k, **v)]

        for k, v in optargs.items():
            if not self.strict:
                v = {**self.template.s_posarg, **v}
                self._fix_default(v)
            v['type'] = Type(v['type'])
            optargs_mapped += [PosArg(name=k, **v)]

        for k, v in kwargs.items():
            if not self.strict:
                v = {**self.template.s_kwarg, **v}
                self._fix_default(v)
            v['type'] = Type(v['type'])
            kwargs_mapped[k] = Kwarg(name=k, **v)

        if varargs is not None:
            if not self.strict:
                varargs = {**self.template.s_varargs, **varargs}
            varargs['type'] = Type(varargs['type'])
            varargs_mapped = VarArgs(**varargs)

        raw['returns'] = Type(raw['returns'])

        # Build function object
        if obj is not None:
            return Method(
                posargs=posargs_mapped,
                optargs=optargs_mapped,
                varargs=varargs_mapped,
                kwargs=kwargs_mapped,
                obj=obj,
                **raw,
            )
        return Function(
            posargs=posargs_mapped,
            optargs=optargs_mapped,
            varargs=varargs_mapped,
            kwargs=kwargs_mapped,
            **raw,
        )

    def _load_function(self, path: Path, obj: T.Optional[Object] = None) -> Function:
        path_label = path.relative_to(self.yaml_dir).as_posix()
        mlog.log('Loading', mlog.bold(path_label))
        raw = self._load(self.read_file(path), self.template.s_function, label=path_label)
        return self._process_function_base(raw)

    def _load_object(self, obj_type: ObjectType, path: Path) -> Object:
        path_label = path.relative_to(self.yaml_dir).as_posix()
        mlog.log(f'Loading', mlog.bold(path_label))
        raw = self._load(self.read_file(path), self.template.s_object, label=path_label)

        def as_methods(mlist: T.List[Function]) -> T.List[Method]:
            res: T.List[Method] = []
            for i in mlist:
                assert isinstance(i, Method)
                res += [i]
            return res

        methods = raw.pop('methods', [])
        obj = Object(methods=[], obj_type=obj_type, **raw)

        newmethods = []
        for x in methods:
            if not self.strict:
                x = {**self.template.s_function, **x}
            newmethods += [self._process_function_base(x, obj)]
        obj.methods = as_methods(newmethods)
        return obj

    def _load_module(self, path: Path) -> T.List[Object]:
        assert path.is_dir()
        module = self._load_object(ObjectType.MODULE, path / 'module.yaml')
        objs = []
        for p in path.iterdir():
            if p.name == 'module.yaml':
                continue
            obj = self._load_object(ObjectType.RETURNED, p)
            obj.defined_by_module = module
            objs += [obj]
        return [module, *objs]

    def load_impl(self) -> ReferenceManual:
        mlog.log('Loading YAML reference manual')
        with mlog.nested():
            manual = ReferenceManual(
                functions=[self._load_function(x) for x in self.func_dir.iterdir()],
                objects=mesonlib.listify([
                    [self._load_object(ObjectType.ELEMENTARY, x) for x in self.elem_dir.iterdir()],
                    [self._load_object(ObjectType.RETURNED, x) for x in self.objs_dir.iterdir()],
                    [self._load_object(ObjectType.BUILTIN, x) for x in self.builtin_dir.iterdir()],
                    [self._load_module(x) for x in self.modules_dir.iterdir()]
                ], flatten=True)
            )

            if not self.strict:
                mlog.warning('YAML reference manual loaded using the best-effort fastyaml loader.  Results are not guaranteed to be stable or correct.')

            return manual
