#
# Copyright (c) Daniel Sheffield 2023
#
# All rights reserved
#
# THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
from bottle import FormsDict
from typing import Iterable, List, Tuple, Union


def get_include_exclude(
        value: Union[str, List, Tuple]
    ) -> Tuple[set[str], set[str]]:
    value = value or ''
    include, exclude = [], []
    if isinstance(value, (list, tuple)):
        for v in value:
            inc, exc = get_include_exclude(v)
            include.extend(inc)
            exclude.extend(exc)
    else:
        inc, exc, *_ = [
            *map(lambda x: x.split('|') if x else [], value.split('!')), []
        ]
        include.extend(inc)
        exclude.extend(exc)
    return set(include), set(exclude)


def get_query_param(include, exclude):
    return '!'.join([
        '|'.join(sorted(include)),
        *([ '|'.join(sorted(exclude)) ] if exclude else [ ]),
    ])


def get_filter(
    query: FormsDict, allow: Iterable[str] = None
) -> dict[str, Tuple[List[str], List[str]]]:
    return {
        k: get_include_exclude(
            (query[k] or 'kg' if k == 'unit' else query.getall(k)) if k in query else None
        ) for k in sorted(set(query.keys()) | set(allow)) if allow is None or k in allow
    }
