"""
This script is used to write `sqf/dababase.py`, that contains all valid SQF expressions.
It reads a file from here:

https://raw.githubusercontent.com/intercept/intercept/master/src/client/headers/client/sqf_pointers_declaration.hpp
"""
import urllib.request

from sqf.interpreter_types import ForType, IfType, SwitchType, WhileType, TryType, WithType
from sqf.types import Code, Array, Boolean, Number, Type, Nothing, Anything, String, Namespace, \
    Object, Config, Script, Control, Group, Display, Side, Task, Location, NetObject, DiaryReport, TeamMember


# The mapping of SQF types to our types
STRING_TO_TYPE = {
    'array': Array,
    'scalar': Number,
    'bool': Boolean,
    'code': Code,
    'string': String,
    'text': String,
    'namespace': Namespace,
    'config': Config,
    'location': Location,
    'object': Object,
    'group': Group,
    'member': TeamMember,  # team_member gets split
    'control': Control,
    'display': Display,
    'exception': TryType,
    'for': ForType,
    'if': IfType,
    'switch': SwitchType,
    'while': WhileType,
    'with': WithType,
    'side': Side,
    'task': Task,
    'script': Script,
    'nan': Number,
    'nothing': Nothing,
    'netobject': NetObject,
    'any': Type,
    'diary': DiaryReport  # diary_record gets split
}

# the argument the type is initialized with
TYPE_TO_INIT_ARGS = {
    Namespace: "'missionNamespace'",
}

# The return type "ANY" means that we do not know it, so it is Nothing()
STRING_TO_TYPE_RETURN = STRING_TO_TYPE.copy()
STRING_TO_TYPE_RETURN['any'] = Anything

WRONG_RETURN_TYPES = {
    'attachedto': Object,
    'getclientstatenumber': Number,
    'handgunmagazine': Array,
    'ammoonpylon': Anything
}


def _parse_type_names(type_names):
    # Alternative types separated by _ char
    types_names = type_names.split('_')

    # Never care about NaN type (covered by scalar)
    if 'nan' in types_names:
        types_names.remove('nan')

    # Remove parts of types that also get split
    if 'team' in types_names:
        types_names.remove('team')
    if 'record' in types_names:
        types_names.remove('record')

    return types_names


def _parse_return_type_names(return_type_names):
    return_type_names = _parse_type_names(return_type_names)

    if len(return_type_names) > 1 and 'nothing' in return_type_names:
        return_type_names.remove('nothing')

    if len(return_type_names) > 1: