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


# Base class for LB Clients
class BaseLbClient(rest_client.RestClient):
    def _show_lb(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_lb(self, uri, req_body):
        resp, body = self.post(url=uri, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _update_lb(self, uri, update_body):
        resp, body = self.put(url=uri, body=json.dumps(update_body))
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _delete_lb(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_lb(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_health_monitor(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 _add_health_monitor(self, uri, req_body):
        resp, body = self.post(url=uri, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _create_port(self, uri, req_body):
        resp, body = self.post(url=uri, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _show_port_options(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 _edit_port_options(self, uri, req_body):
        resp, body = self.put(url=uri, body=json.dumps(req_body))
        self.expected_success(200, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _bind_real_server(self, uri, req_body):
        resp, body = self.post(url=uri, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _deploy_lb(self, uri, req_body):
        resp, body = self.post(url=uri, body=json.dumps(req_body))
        self.expected_success(202, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _stop_lb(self, uri):
        resp, body = self.post(url=uri, body={})
        self.expected_success(202, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _show_lb_status(self, uri):
        headers = {"Content-Type": "application/text; charset=utf-8"}
        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_revisions(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 _show_revision(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 _list_jobs(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 _show_job(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_revision(self, uri, req_body):
        resp, body = self.post(url=uri, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _start_drain_servers(self, uri, req_body):
        resp, body = self.post(url=uri, body=json.dumps(req_body))
        self.expected_success(201, resp.status)
        body = json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _list_drain_servers(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 _stop_drain_servers(self, uri):
        headers = {"Accept": "application/json"}
        resp, body = self.delete(url=uri, headers=headers)
        self.expected_success(204, resp.status)
        # As the Stop drain servers API returns an empty byte str even though in 204 http code,
        # so need to set empty byte str to empty json
        body = {} if body == b"" else json.loads(body)
        return rest_client.ResponseBody(resp, body)

    def _list_lb_instance(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 _get_latest_cert(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)
