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

from __future__ import annotations

from .. import mesonlib, mparser
from .exceptions import InterpreterException, InvalidArguments
from ..coredata import UserOption


import collections.abc
import typing as T

if T.TYPE_CHECKING:
    from .baseobjects import TYPE_var, TYPE_kwargs, SubProject

def flatten(args: T.Union['TYPE_var', T.List['TYPE_var']]) -> T.List['TYPE_var']:
    if isinstance(args, mparser.BaseStringNode):
        assert isinstance(args.value, str)
        return [args.value]
    if not isinstance(args, collections.abc.Sequence):
        return [args]
    result: T.List['TYPE_var'] = []
    for a in args:
        if isinstance(a, list):
            rest = flatten(a)
            result = result + rest
        elif isinstance(a, mparser.BaseStringNode):
            result.append(a.value)
        else:
            result.append(a)
    return result

def resolve_second_level_holders(args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> T.Tuple[T.List['TYPE_var'], 'TYPE_kwargs']:
    def resolver(arg: 'TYPE_var') -> 'TYPE_var':
        if isinstance(arg, list):
            return [resolver(x) for x in arg]
        if isinstance(arg, dict):
            return {k: resolver(v) for k, v in arg.items()}
        if isinstance(arg, mesonlib.SecondLevelHolder):
            return arg.get_default_object()
        return arg
    return [resolver(x) for x in args], {k: resolver(v) for k, v in kwargs.items()}

def default_resolve_key(key: mparser.BaseNode) -> str:
    if not isinstance(key, mparser.IdNode):
        raise InterpreterException('Invalid kwargs format.')
    return key.value

def stringifyUserArguments(args: TYPE_var, subproject: SubProject, quote: bool = False) -> str:
    if isinstance(args, str):
        return f"'{args}'" if quote else args
    elif isinstance(args, bool):
        return 'true' if args else 'false'
    elif isinstance(args, int):
        return str(args)
    elif isinstance(args, list):
        return '[%s]' % ', '.join([stringifyUserArguments(x, subproject, True) for x in args])
    elif isinstance(args, dict):
        l = ['{} : {}'.format(stringifyUserArguments(k, subproject, True),
                              stringifyUserArguments(v, subproject, True)) for k, v in args.items()]
        return '{%s}' % ', '.join(l)
    elif isinstance(args, UserOption):
        from .decorators import FeatureNew
        FeatureNew.single_use('User option in string format', '1.3.0', subproject)
        return stringifyUserArguments(args.printable_value(), subproject)
    raise InvalidArguments('Value other than strings, integers, bools, options, dictionaries and lists thereof.')
