import json
from urllib import parse as urllib
from abc import ABC, abstractmethod
from lib.common import rest_client
from lib.services.flava_pulsar.base_client import BaseClient

class PulsarClient(BaseClient):
    """Service client for Flava MQ for pulsar API"""

    def __init__(self, auth_provider, client, **kwargs):
        super().__init__(auth_provider=auth_provider, **kwargs)
        self.client = client

    def _build_url(self, additional_path="", params=None):
        url = (
            "/global/flava/v2/" + additional_path
        )
        if params:
            url += f"?{urllib.urlencode(params)}"
        return url

    def _parse_response(self, resp, body, schema):
        body = json.loads(body)
        self.validate_response(schema, resp, body)
        return rest_client.ResponseBody(resp, body)

    def list_namespace(self, tenant):
        """List Namespace."""
        url = self._build_url(additional_path=f"namespaces/{tenant}")
        resp, body = self.get(url)
        return self._parse_response(
            resp, body, self.client.get_schema().list_namespace
        )

    def get_namespace(self, name, tenant):
        """Get Namespace."""
        url = self._build_url(additional_path=f"namespaces/{tenant}/{name}")
        resp, body = self.get(url)
        return self._parse_response(
            resp, body, self.client.get_schema().get_namespace
        )

    def create_namespace(self, name, tenant, body_data):
        """Create Namespace."""
        url = self._build_url(additional_path=f"namespaces/{tenant}/{name}")
        url += "?createTenantIfMissing=true"
        post_body = json.dumps(body_data)
        resp, body = self.put(url, post_body)
        # If body empty, need to fix empty json str
        body = "{}" if body == b"" else json.loads(body)
        return self._parse_response(
            resp, body, self.client.get_schema().create_namespace
        )

    def update_namespace(self, name, tenant, body_data):
        """Update Namespace."""
        url = self._build_url(additional_path=f"namespaces/{tenant}/{name}/policies")
        post_body = json.dumps(body_data)
        resp, body = self.post(url, post_body)
        # If body empty, need to fix empty json str
        body = "{}" if body == b"" else json.loads(body)
        return self._parse_response(
            resp, body, self.client.get_schema().update_namespace
        )

    def delete_namespace(self, name, tenant):
        """Delete Namespace."""
        url = self._build_url(additional_path=f"namespaces/{tenant}/{name}")
        resp, body = self.delete(url)
        # If body empty, need to fix empty json str
        body = "{}" if body == b"" else json.loads(body)
        return self._parse_response(
            resp, body, self.client.get_schema().delete_namespace
        )

class PulsarClientInterface(ABC):
    @abstractmethod
    def get_schema(self):
        pass
