from lib.common import rest_client
from oslo_serialization import jsonutils as json


# Base class for VPC Clients
class BaseVpcClient(rest_client.RestClient):
    def _read_routing_gateway(self, uri):
        resp, body = self.get(url=uri)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _create_routing_gateway(self, uri, req_body):
        headers = {"Accept": "application/json"}
        resp, body = self.post(url=uri, headers=headers, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _patch_routing_gateway(self, uri, update_body):
        headers = {"Accept": "application/json"}
        resp, body = self.patch(url=uri, headers=headers, body=json.dumps(update_body))
        self.expected_success(200, resp.status)
        # As the 'PATCH' routing API server returns an empty byte string even though in 200 http code,
        # below if is needed
        if body == b"":
            body = {}
        else:
            body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _delete_routing_gateway(self, uri):
        resp, body = self.delete(url=uri)
        self.expected_success(204, resp.status)
        body = json.loads(json.dumps(body))
        return rest_client.ResponseBody(resp, body)

    def _list_routing_gateway(self, uri):
        headers = {"Accept": "application/json"}
        resp, body = self.get(url=uri, headers=headers)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _create_acl_policy(self, uri, req_body):
        headers = {"Accept": "application/json"}
        resp, body = self.post(url=uri, headers=headers, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _delete_acl_policy(self, uri, flava_vpc=False):
        resp, body = self.delete(url=uri)
        if flava_vpc:
            self.expected_success(200, resp.status)
        else:
            self.expected_success(204, resp.status)
        # As the 'DEL' API server returns an empty byte string even though in 200 http code,
        # below if is needed
        if body == b"":
            body = {}
        else:
            body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _list_acl_policy(self, uri):
        headers = {"Accept": "application/json"}
        resp, body = self.get(url=uri, headers=headers)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _read_acl_policy(self, uri):
        resp, body = self.get(url=uri)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _patch_acl_policy(self, uri, update_body, flava_vpc=False):
        headers = {"Accept": "application/json"}
        if flava_vpc:
            resp, body = self.put(url=uri, headers=headers, body=json.dumps(update_body))
        else:
            resp, body = self.patch(url=uri, headers=headers, body=json.dumps(update_body))
        self.expected_success(200, resp.status)
        # As the 'PATCH' API server returns an empty byte string even though in 200 http code,
        # below if is needed
        if body == b"":
            body = {}
        else:
            body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _read_nat_gateway(self, uri):
        resp, body = self.get(url=uri)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _create_nat_gateway(self, uri, req_body):
        headers = {"Accept": "application/json"}
        resp, body = self.post(url=uri, headers=headers, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _patch_nat_gateway(self, uri, update_body):
        headers = {"Accept": "application/json"}
        resp, body = self.patch(url=uri, headers=headers, body=json.dumps(update_body))
        self.expected_success(200, resp.status)
        # As the 'PATCH' NAT API server returns an empty byte string even though in 200 http code,
        # below if is needed
        if body == b"":
            body = {}
        else:
            body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _delete_nat_gateway(self, uri):
        resp, body = self.delete(url=uri)
        self.expected_success(204, resp.status)
        body = json.loads(json.dumps(body))
        return rest_client.ResponseBody(resp, body)

    def _list_nat_gateway(self, uri):
        headers = {"Accept": "application/json"}
        resp, body = self.get(url=uri, headers=headers)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _list_reserved_ip(self, uri):
        headers = {"Accept": "application/json"}
        resp, body = self.get(url=uri, headers=headers)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _create_reserved_ip(self, uri, req_body):
        headers = {"Accept": "application/json"}
        resp, body = self.post(url=uri, headers=headers, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _read_reserved_ip(self, uri):
        resp, body = self.get(url=uri)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _delete_reserved_ip(self, uri):
        resp, body = self.delete(url=uri)
        self.expected_success(200, resp.status)
        # As the 'DEL' API server returns an empty byte string even though in 200 http code,
        # below if is needed
        if body == b"":
            body = {}
        else:
            body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _patch_reserved_ip(self, uri, update_body):
        headers = {"Accept": "application/json"}
        resp, body = self.put(url=uri, headers=headers, body=json.dumps(update_body))
        self.expected_success(200, resp.status)
        # As the 'PATCH' API server returns an empty byte string even though in 200 http code,
        # below if is needed
        if body == b"":
            body = {}
        else:
            body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _create_vpc(self, uri, req_body):
        headers = {"Accept": "application/json"}
        resp, body = self.post(url=uri, headers=headers, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _read_vpc(self, uri):
        resp, body = self.get(url=uri)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _delete_vpc(self, uri):
        resp, body = self.delete(url=uri)
        self.expected_success(200, resp.status)
        # As the 'DEL' API server returns an empty byte string even though in 200 http code,
        # below if is needed
        if body == b"":
            body = {}
        else:
            body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _list_vpc(self, uri):
        headers = {"Accept": "application/json"}
        resp, body = self.get(url=uri, headers=headers)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _patch_vpc(self, uri, update_body):
        headers = {"Accept": "application/json"}
        resp, body = self.put(url=uri, headers=headers, body=json.dumps(update_body))
        self.expected_success(200, resp.status)
        # As the 'PATCH' API server returns an empty byte string even though in 200 http code,
        # below if is needed
        if body == b"":
            body = {}
        else:
            body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _create_external_ip(self, uri, req_body):
        headers = {"Accept": "application/json"}
        resp, body = self.post(url=uri, headers=headers, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _read_external_ip(self, uri):
        resp, body = self.get(url=uri)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _delete_external_ip(self, uri):
        resp, body = self.delete(url=uri)
        self.expected_success(200, resp.status)
        # As the 'DEL' API server returns an empty byte string even though in 200 http code,
        # below if is needed
        if body == b"":
            body = {}
        else:
            body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _patch_external_ip(self, uri, update_body):
        headers = {"Accept": "application/json"}
        resp, body = self.put(url=uri, headers=headers, body=json.dumps(update_body))
        self.expected_success(200, resp.status)
        # As the 'PATCH' API server returns an empty byte string even though in 200 http code,
        # below if is needed
        if body == b"":
            body = {}
        else:
            body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _list_external_ip(self, uri):
        headers = {"Accept": "application/json"}
        resp, body = self.get(url=uri, headers=headers)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _list_cluster_acl_policy(self, uri):
        headers = {"Accept": "application/json"}
        resp, body = self.get(url=uri, headers=headers)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _read_cluster_acl_policy(self, uri):
        resp, body = self.get(url=uri)
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)
