
from flask import current_app, Flask, Response
from ..core.responses import internal_server_error, forbidden_error ,make_response, not_found_error
from ..models.discovered_apis import DiscoveredAPIs
from ..util import serialize_clean_camel_case
from ..core.resources import Resource
import json


class DiscoverApisOperations(Resource):

    def get_discoveredapis(self, api_invoker_id, query_params):

        services = self.db.get_col_by_name(self.db.service_api_descriptions)
        invokers = self.db.get_col_by_name(self.db.invoker_col)

        current_app.logger.debug("Discovering services apis by: " + api_invoker_id)

        try:
            invoker = invokers.find_one({"api_invoker_id": api_invoker_id})
            if invoker is None:
                current_app.logger.error("Api invoker not found in database")
                return not_found_error(detail="API Invoker does not exist", cause="API Invoker id not found")

            my_params = []
            my_query = {}
            # QPV = Query Parameter Value
            query_params_name = {
                "api_name": "api_name",
                "api_version": '{"aef_profiles": {"$elemMatch": {"versions" : {"$elemMatch": {"api_version": "QPV"}}}}}',
                "comm_type": '{"aef_profiles": {"$elemMatch": {"versions" : {"$elemMatch": {"resources": {"$elemMatch": {"comm_type":"QPV"}}}}}}}',
                "protocol": '{"aef_profiles": {"$elemMatch": {"protocol":"QPV"}}}',
                "aef_id": '{"aef_profiles": {"$elemMatch": {"aef_id":"QPV"}}}',
                "data_format": '{"aef_profiles": {"$elemMatch": {"data_format":"QPV"}}}',
                "api_cat": "service_api_category",
                "supported_features": "supported_features",
                "api_supported_features": "api_supp_feats"
            }

            for param in query_params:
                current_app.logger.info(query_params[param])
                if query_params[param] is not None:
                    if "vend-spec" in param:
                        current_app.logger.info("vend-spec in param")
                        attribute_path = query_params[param]["target"].split('/')
                        attribute = "aef_profiles.0." + attribute_path[1] + "." + attribute_path[2]
                        my_params.append({attribute: query_params[param]["value"]})
                    elif param in ["api_version", "comm_type", "protocol", "aef_id", "data_format"]:
                        current_app.logger.info(query_params_name[param])
                        current_app.logger.info(query_params_name[param].replace("QPV", query_params[param]))
                        my_params.append(json.loads(query_params_name[param].replace("QPV", query_params[param])))
                    else:
                        my_params.append({query_params_name[param]: query_params[param]})

            if my_params:
                my_query = {"$and": my_params}

            discoved_apis = services.find(my_query, {"_id":0, "api_name":1, "api_id":1, "aef_profiles":1, "description":1, "supported_features":1, "shareable_info":1, "service_api_category":1, "api_supp_feats":1, "pub_api_path":1, "ccf_id":1})
            json_docs = []
            for discoved_api in discoved_apis:
                json_docs.append(discoved_api)

            if len(json_docs) == 0:
                return not_found_error(detail="API Invoker " + api_invoker_id + " has no API Published that accomplish filter conditions", cause="No API Published accomplish filter conditions")

            apis_discovered = DiscoveredAPIs(service_api_descriptions=json_docs)
            res = make_response(object=serialize_clean_camel_case(apis_discovered), status=200)
            return res

        except Exception as e:
            exception = "An exception occurred in discover services"
            current_app.logger.error(exception + "::" + str(e))
            return internal_server_error(detail=exception, cause=str(e))

