from http import HTTPStatus

import requests
from requests import Response

from model.cli.command.http.Contants import STANDARD_ENGINE_NAME
from model.http.engine.HttpEngineModel import AbstractHttpEngine
from model.http.info.body.BodyModel import Body
from model.http.info.cookie.CookieModel import Cookies
from model.http.info.header.HeaderModel import Headers
from model.http.info.data.DataModel import AbstractHttpData
from model.http.info.parameter.ParameterModel import Parameters
from model.http.info.content.ResponseModel import ResponseContent


class StandardHttpEngine(AbstractHttpEngine):
    def __init__(self):
        super().__init__(STANDARD_ENGINE_NAME)

    def _do_get(self, http_request: AbstractHttpData) -> ResponseContent:
        return self._execute_request(http_request.get_http_method(),
                                     http_request)

    def _do_post(self, http_request: AbstractHttpData) -> ResponseContent:
        return self._execute_request(http_request.get_http_method(),
                                     http_request)

    def _do_put(self, http_request: AbstractHttpData) -> ResponseContent:
        return self._execute_request(http_request.get_http_method(),
                                     http_request)

    def _do_delete(self, http_request: AbstractHttpData) -> ResponseContent:
        return self._execute_request(http_request.get_http_method(), http_request)

    def _do_patch(self, http_request: AbstractHttpData) -> ResponseContent:
        return self._execute_request(http_request.get_http_method(), http_request)

    def _execute_request(self, method: str, request: AbstractHttpData) -> ResponseContent:
        response: Response = requests.request(method=method,
                                              url=request.get_http_request().get_endpoint().dump(),
                                              params=request.get_http_request().get_parameters().dump(),
                                              headers=request.get_http_request().get_headers().dump(),
                                              data=request.get_http_request().get_body().get_content())
        return ResponseContent.create_response(endpoint=request.get_http_request().get_endpoint(),
                                               status_code=HTTPStatus(
                                                   response.status_code),
                                               headers=Headers.from_dictionary(
                                                   response.headers),
                                               parameters=Parameters.from_list(
                                                   []),
                                               cookies=Cookies.from_string_collection(
                                                   response.cookies.items()),
                                               body=Body.from_string(response.text))
