#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import logging

import requests
import certifi

from tikit.tencentcloud.common.http.pre_conn import PreConnAdapter

try:
    from urllib.parse import urlparse
except ImportError:
    from urlparse import urlparse

from tikit.tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException

logger = logging.getLogger("tencentcloud_sdk_common")


def _get_proxy_from_env(host, varname="HTTPS_PROXY"):
    no_proxy = os.environ.get("NO_PROXY") or os.environ.get("no_proxy")
    if no_proxy and host in no_proxy:
        return None
    return os.environ.get(varname.lower()) or os.environ.get(varname.upper())


class ProxyConnection(object):
    def __init__(self, host, timeout=60, proxy=None, certification=None, is_http=False, pre_conn_pool_size=0):
        self.request_host = host
        self.certification = certification
        if certification is None:
            self.certification = certifi.where()
        self.timeout = timeout
        self.proxy = None
        if is_http:
            proxy = proxy or _get_proxy_from_env(host, varname="HTTP_PROXY")
        else:
            proxy = proxy or _get_proxy_from_env(host, varname="HTTPS_PROXY")
        if proxy:
            self.proxy = {"http": proxy, "https": proxy}
        self.request_length = 0
        self._session = requests.Session()
        if pre_conn_pool_size > 0:
            adapter = PreConnAdapter(conn_pool_size=pre_conn_pool_size)
            self._session.mount("https://", adapter)
            self._session.mount("http://", adapter)

    def request(self, method, url, body=None, headers=None):
        headers.setdefault("Host", self.request_host)
        return self._session.request(method=method,
                                     url=url,
                                     data=body,
                                     headers=headers,
                                     proxies=self.proxy,
                                     verify=self.certification,
                                     timeout=self.timeout,
                                     stream=True)


class ApiRequest(object):
    def __init__(self, host, req_timeout=60, debug=False, proxy=None, is_http=False, certification=None,
                 pre_conn_pool_size=0):
        self.conn = ProxyConnection(host, timeout=req_timeout, proxy=proxy, certification=certification,
                                    is_http=is_http, pre_conn_pool_size=pre_conn_pool_size)
        self.is_http = is_http
        self.host = host
        self.req_timeout = req_timeout
        self.keep_alive = False
        self.debug = debug
        self.request_size = 0
        self.response_size = 0

    def _handle_host(self, host):
        url = urlparse(host)
        if not url.hostname:
            if self.is_http:
                return "http://" + host
            else:
                return "https://" + host
        return host

    def set_req_timeout(self, req_timeout):
        self.req_timeout = req_timeout

    def is_keep_alive(self):
        return self.keep_alive

    def set_keep_alive(self, flag=True):
        self.keep_alive = flag

    def set_debug(self, debug):
        self.debug = debug

    def _request(self, req_inter):
        url = self._handle_host(req_inter.host)
        if self.keep_alive:
            req_inter.header["Connection"] = "Keep-Alive"
        logger.debug("SendRequest: %s" % req_inter)
        if req_inter.method == 'GET':
            req_inter_url = '%s?%s' % (url, req_inter.data)
            return self.conn.request(req_inter.method, req_inter_url,
                                     None, req_inter.header)
        elif req_inter.method == 'POST':
            return self.conn.request(req_inter.method, url,
                                     req_inter.data, req_inter.header)
        else:
            raise TencentCloudSDKException(
                "ClientParamsError", 'Method only support (GET, POST)')

    def send_request(self, req_inter):
        try:
            http_resp = self._request(req_inter)
            self.request_size = self.conn.request_length
            return http_resp
        except Exception as e:
            raise TencentCloudSDKException("ClientNetworkError", str(e))


class RequestInternal(object):
    def __init__(self, host="", method="", uri="", header=None, data=""):
        if header is None:
            header = {}
        self.host = host
        self.method = method
        self.uri = uri
        self.header = header
        self.data = data

    def __str__(self):
        headers = "\n".join("%s: %s" % (k, v) for k, v in self.header.items())
        return ("Host: %s\nMethod: %s\nUri: %s\nHeader: %s\nData: %s\n"
                % (self.host, self.method, self.uri, headers, self.data))


class ResponsePrettyFormatter(object):
    def __init__(self, resp, format_body=True, delimiter="\n"):
        self._resp = resp
        self._format_body = format_body
        self._delimiter = delimiter

    def __str__(self):
        lines = ['%s %d %s' % (self.str_ver(self._resp.raw.version), self._resp.status_code, self._resp.reason)]
        for k, v in self._resp.headers.items():
            lines.append('%s: %s' % (k, v))
        if self._format_body:
            lines.append('')
            lines.append(self._resp.text)
        return self._delimiter.join(lines)

    @staticmethod
    def str_ver(ver):
        if ver == 10:
            return "HTTP/1.0"
        elif ver == 11:
            return "HTTP/1.1"
        elif ver == 20:
            return "HTTP/2.0"
        else:
            return str(ver)
