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 ..core.responses import bad_request_error
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]]
    """

    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_prov_name": req_api_prov_name, "api_supported_features": api_supported_features,
                    "supported_features": supported_features, "ue_ip_addr": ue_ip_addr }

    if supported_features is not None:
        supp_feat_dict = DiscoveredAPIs.return_supp_feat_dict(supported_features)

        # vs_fields_exist = False
        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])
                    # vs_fields_exist = True
            # if not vs_fields_exist:
            #     return bad_request_error(
            #         detail="If VendorExt feature is enabled, then vendor-specific parameters are mandatory",
            #         cause="Mandatory parameters missing",
            #         invalid_params=[{"param": "vendor extensibility parameters", "reason": "missing"}]
            #     )
        if supp_feat_dict['RNAA']:
            if not query_params["api_prov_name"] and not query_params["ue_ip_addr"]:
                return bad_request_error(detail="req_api_prov_name or ue_ip_addr parameters are mandatory when RNAA is enabled",
                                         cause="Mandatory parameters missing", invalid_params=[
                        {"param": "req-api-prov-name or ue-ip-addr", "reason": "missing"}])

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