from typing import Dict
from typing import Tuple
from typing import Union

from service_apis.models.aef_location import AefLocation  # noqa: E501
from service_apis.models.communication_type import CommunicationType  # noqa: E501
from service_apis.models.data_format import DataFormat  # noqa: E501
from service_apis.models.discovered_apis import DiscoveredAPIs  # noqa: E501
from service_apis.models.ip_addr_info import IpAddrInfo  # noqa: E501
from service_apis.models.problem_details import ProblemDetails  # noqa: E501
from service_apis.models.protocol import Protocol  # noqa: E501
from service_apis.models.service_kpis import ServiceKpis  # noqa: E501
from service_apis import util

from ..core.discoveredapis import DiscoverApisOperations
from flask import Response, request, current_app
import json

discover_apis = DiscoverApisOperations()


def all_service_apis_get(api_invoker_id, api_name=None, api_version=None, comm_type=None, protocol=None, aef_id=None, data_format=None, api_cat=None, preferred_aef_loc=None, req_api_prov_name=None, supported_features=None, api_supported_features=None, ue_ip_addr=None, service_kpis=None):  # noqa: E501
    """all_service_apis_get

    Discover published service APIs and retrieve a collection of APIs according to certain filter criteria.  # noqa: E501

    :param api_invoker_id: String identifying the API invoker assigned by the CAPIF core function. It also represents the CCF identifier in the CAPIF-6/6e interface. 
    :type api_invoker_id: str
    :param api_name: API name, it is set as {apiName} part of the URI structure as defined in clause 5.2.4 of 3GPP TS 29.122. 
    :type api_name: str
    :param api_version: API major version the URI (e.g. v1).
    :type api_version: str
    :param comm_type: Communication type used by the API (e.g. REQUEST_RESPONSE).
    :type comm_type: dict | bytes
    :param protocol: Protocol used by the API.
    :type protocol: dict | bytes
    :param aef_id: AEF identifer.
    :type aef_id: str
    :param data_format: Data formats used by the API (e.g. serialization protocol JSON used).
    :type data_format: dict | bytes
    :param api_cat: The service API category to which the service API belongs to.
    :type api_cat: str
    :param preferred_aef_loc: The preferred AEF location.
    :type preferred_aef_loc: dict | bytes
    :param req_api_prov_name: Represents the required API provider name.
    :type req_api_prov_name: str
    :param supported_features: Features supported by the NF consumer for the CAPIF Discover Service API.
    :type supported_features: str
    :param api_supported_features: Features supported by the discovered service API indicated by api-name parameter. This may only be present if api-name query parameter is present. 
    :type api_supported_features: str
    :param ue_ip_addr: Represents the UE IP address information.
    :type ue_ip_addr: dict | bytes
    :param service_kpis: Contains iInformation about service characteristics provided by the targeted  service API(s). 
    :type service_kpis: dict | bytes

    :rtype: Union[DiscoveredAPIs, Tuple[DiscoveredAPIs, int], Tuple[DiscoveredAPIs, int, Dict[str, str]]
    """
    if request.is_json:
        comm_type = CommunicationType.from_dict(request.get_json()())  # noqa: E501
    if request.is_json:
        protocol = Protocol.from_dict(request.get_json()())  # noqa: E501
    if request.is_json:
        data_format = DataFormat.from_dict(request.get_json()())  # noqa: E501
    if request.is_json:
        preferred_aef_loc = AefLocation.from_dict(request.get_json()())  # noqa: E501
    if request.is_json:
        ue_ip_addr = IpAddrInfo.from_dict(request.get_json()())  # noqa: E501
    if request.is_json:
        service_kpis = ServiceKpis.from_dict(request.get_json()())  # noqa: E501
    current_app.logger.info("Discovering service apis")

    query_params = {"api_name": api_name, "api_version": api_version, "comm_type": comm_type,
                    "protocol": protocol, "aef_id": aef_id, "data_format": data_format,
                    "api_cat": api_cat, "api_supported_features": api_supported_features,
                    "supported_features": supported_features}

    if supported_features is not None:
        supp_feat_dict = DiscoveredAPIs.return_supp_feat_dict(supported_features)
        current_app.logger.info(supp_feat_dict)
        if supp_feat_dict['VendSpecQueryParams']:
            for q_params in request.args:
                if "vend-spec" in q_params:
                    query_params[q_params] = json.loads(request.args[q_params])

    response = discover_apis.get_discoveredapis(api_invoker_id, query_params)
    return response
