# encoding: utf-8

from ctyun.auth.authsigner import SignV2Auth, SignV4Auth
from ctyun.http.util import HttpClient

from ctyun.man.model.getConnection import GetConnectionRequest
from ctyun.man.model.getConnection import GetConnectionResult

from ctyun.man.model.getBandwidth import GetBandwidthRequest
from ctyun.man.model.getBandwidth import GetBandwidthResult

from ctyun.man.model.getAvailBw import GetAvailBwRequest
from ctyun.man.model.getAvailBw import GetAvailBWResult

from ctyun.man.model.getCapacity import GetCapacityRequest
from ctyun.man.model.getCapacity import GetCapacityResult

from ctyun.man.model.getUsage import GetUsageRequest
from ctyun.man.model.getUsage import GetUsageResult

from ctyun.man.model.getUsageV5 import GetUsageV5Request
from ctyun.man.model.getUsageV5 import GetUsageV5Result

from ctyun.man.model.getDeleteCapacity import GetDeleteCapacityRequest
from ctyun.man.model.getDeleteCapacity import GetDeleteCapacityResult

from ctyun.man.model.getTraffics import GetTrafficsRequest
from ctyun.man.model.getTraffics import GetTrafficsResult

from ctyun.man.model.getAvailableBandwidth import GetAvailableBandwidthRequest
from ctyun.man.model.getAvailableBandwidth import GetAvailableBandwidthResult

from ctyun.man.model.getRequests import GetRequestsRequest
from ctyun.man.model.getRequests import GetRequestsResult

from ctyun.man.model.getReturnCode import GetReturnCodeRequest
from ctyun.man.model.getReturnCode import GetReturnCodeResult

from ctyun.man.model.getConcurrentConnection import GetConcurrentConnectionRequest
from ctyun.man.model.getConcurrentConnection import GetConcurrentConnectionResult
from oos.DomainConfig import *
from ooscore.exceptions import *

SERVICE_NAME = "s3"  # "mg"  #"s3"                                # service name
USE_SSL = True


class ManagementClient(object):
    endpoint = ""

    def __init__(self, credentials, client_config, endpoint, sign_payload=False):
        self._credentials = credentials
        self._client_config = client_config
        self.endpoint = endpoint
        self.sign_payload = sign_payload

    def get_user_agent(self):
        return 'ctyun-oos-python-sdk/6.5.7'

    def get_capacity(self, req) -> GetCapacityResult:
        """
        :type req GetCapacityRequest
        :param req
        :return: GetCapacityResult
        """
        domain = DomainConfig()
        # if domain.is_s5_endpoint(self.endpoint):
        #    raise CallMethodError(call_method='get_capacity', endpoint_url=self.endpoint)
        result = GetCapacityResult()
        result = self.invoke(req, result)
        return result

    def get_delete_capacity(self, req) -> GetDeleteCapacityResult:
        """
        :type req GetDeleteCapacityRequest
        :param req
        :return: GetDeleteCapacityResult
        """
        domain = DomainConfig()
        if domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_delete_capacity', endpoint_url=self.endpoint)
        result = GetDeleteCapacityResult()
        result = self.invoke(req, result)
        return result

    def get_traffics(self, req) -> GetTrafficsResult:
        """
        :type req GetTrafficsRequest
        :param req
        :return: GetTrafficsResult
        """
        domain = DomainConfig()
        if domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_traffics', endpoint_url=self.endpoint)
        result = GetTrafficsResult()
        result = self.invoke(req, result)
        return result

    def get_available_bandwidth(self, req) -> GetAvailableBandwidthResult:
        """
        :type req GetAvailableBandwidthRequest
        :param req
        :return: GetAvailableBandwidthResult
        """
        domain = DomainConfig()
        if domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_available_bandwidth', endpoint_url=self.endpoint)
        result = GetAvailableBandwidthResult()
        result = self.invoke(req, result)
        return result

    def get_avail_bw(self, req) -> GetAvailBWResult:
        """
        :type req GetAvailBwRequest
        :param req
        :return: GetAvailBWResult
        """
        domain = DomainConfig()
        if domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_avail_bw', endpoint_url=self.endpoint)
        result = GetAvailBWResult()
        result = self.invoke(req, result)
        return result

    def get_requests(self, req) -> GetRequestsResult:
        """
        :type req GetRequestsRequest
        :param req
        :return: GetRequestsResult
        """
        domain = DomainConfig()
        if domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_requests', endpoint_url=self.endpoint)
        result = GetRequestsResult()
        result = self.invoke(req, result)
        return result

    def get_return_code(self, req) -> GetReturnCodeResult:
        """
        :type req GetReturnCodeRequest
        :param req
        :return: GetReturnCodeResult
        """
        domain = DomainConfig()
        if domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_return_code', endpoint_url=self.endpoint)
        result = GetReturnCodeResult()
        result = self.invoke(req, result)
        return result

    def get_concurrent_connection(self, req) -> GetConcurrentConnectionResult:
        """
        :type req GetConcurrentConnectionRequest
        :param req
        :return: GetConcurrentConnectionResult
        """
        domain = DomainConfig()
        if domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_concurrent_connection', endpoint_url=self.endpoint)
        result = GetConcurrentConnectionResult()
        result = self.invoke(req, result)
        return result

    def get_usage(self, req) -> GetUsageResult:
        """
        :type req GetUsageRequest
        :param req
        :return:GetUsageResult
        """
        domain = DomainConfig()
        if domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_usage', endpoint_url=self.endpoint)
        result = GetUsageResult()
        result = self.invoke(req, result)
        return result

    def get_usage_v5(self, req) -> GetUsageV5Result:
        """
        :type req GetUsageV5Request
        :param req
        :return:GetUsageV5Result
        """
        domain = DomainConfig()
        if not domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_usage_v5', endpoint_url=self.endpoint)
        result = GetUsageV5Result()
        result = self.invoke(req, result)
        return result

    def get_connection(self, req) -> GetConnectionResult:
        """
        :type req GetConnectionRequest
        :param req
        :return:GetUsageResult
        """
        domain = DomainConfig()
        if domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_connection', endpoint_url=self.endpoint)
        result = GetConnectionResult()
        result = self.invoke(req, result)
        return result

    def get_bandwidth(self, req) -> GetBandwidthResult:
        """
        :type req GetBandwidthRequest
        :param req
        :return:GetBandwidthResult
        """
        domain = DomainConfig()
        if domain.is_s5_endpoint(self.endpoint):
            raise CallMethodError(call_method='get_bandwidth', endpoint_url=self.endpoint)
        result = GetBandwidthResult()
        result = self.invoke(req, result)
        return result

    def invoke(self, req, result):
        # "http://oos-xxx.ctyunapi.cn:80
        _endpoint = self.endpoint.lower().replace("http://", "").replace("https://", "")

        # region_name = _endpoint[4:_endpoint.find("-mg")]
        region_name = _endpoint[4:_endpoint.find(".ctyunapi.cn")]
        if _endpoint.find(":") > 0:
            _endpoint = _endpoint[0: _endpoint.find(":")]

        host = _endpoint
        headers = {
            'Host': host,
            'User-Agent': self.get_user_agent(),
            'Content-Type': 'application/octet-stream',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
        }
        # headers['User-Agent'] = 'oos-sdk-python/6.5.0'
        params = req.get_params()

        http_client = HttpClient(
            self.endpoint, headers=headers, method="GET", params=params)

        if self._client_config.signature_version.lower() == "v2":
            v2auth = SignV2Auth(self._credentials)
            v2auth.add_auth(http_client)
        else:
            v4auth = SignV4Auth(self._credentials, SERVICE_NAME, region_name, http_client, self.sign_payload)
            v4auth.add_auth(http_client)

        result = http_client.request(result, use_http2=False)

        return result
