from __future__ import print_function

import base64
import contextlib
import copy
import email.utils
import functools
import gzip
import hashlib
import httplib2
import os
import random
import re
import shutil
import six
import socket
import ssl
import struct
import sys
import threading
import time
import traceback
import zlib
from six.moves import http_client, queue


DUMMY_URL = "http://127.0.0.1:1"
DUMMY_HTTPS_URL = "https://127.0.0.1:2"

tls_dir = os.path.join(os.path.dirname(__file__), "tls")
CA_CERTS = os.path.join(tls_dir, "ca.pem")
CA_UNUSED_CERTS = os.path.join(tls_dir, "ca_unused.pem")
CLIENT_PEM = os.path.join(tls_dir, "client.pem")
CLIENT_ENCRYPTED_PEM = os.path.join(tls_dir, "client_encrypted.pem")
SERVER_PEM = os.path.join(tls_dir, "server.pem")
SERVER_CHAIN = os.path.join(tls_dir, "server_chain.pem")


@contextlib.contextmanager
def assert_raises(exc_type):
    def _name(t):
        return getattr(t, "__name__", None) or str(t)

    if not isinstance(exc_type, tuple):
        exc_type = (exc_type,)
    names = ", ".join(map(_name, exc_type))

    try:
        yield
    except exc_type:
        pass
    else:
        assert False, "Expected exception(s) {0}".format(names)


class BufferedReader(object):
    """io.BufferedReader with \r\n support
    """

    def __init__(self, sock):
        self._buf = b""
        self._end = False
        self._newline = b"\r\n"
        self._sock = sock
        if isinstance(sock, bytes):
            self._sock = None
            self._buf = sock

    def _fill(self, target=1, more=None, untilend=False):
        if more:
            target = len(self._buf) + more
        while untilend or (len(self._buf) < target):
            # crutch to enable HttpRequest.from_bytes
            if self._sock is None:
                chunk = b""
            else:
                chunk = self._sock.recv(8 << 10)
            # print("!!! recv", chunk)
            if not chunk:
                self._end = True
                if untilend:
                    return
                else:
                    raise EOFError
            self._buf += chunk

    def peek(self, size):
        self._fill(target=size)
        return self._buf[:size]

    def read(self, size):
        self._fill(target=size)
        chunk, self._buf = self._buf[:size], self._buf[size:]
        return chunk

    def readall(self):
        self._fill(untilend=True)
        chunk, self._buf = self._buf, b""
        return chunk

    def readline(self):
        while True:
            i = self._buf.find(self._newline)
            if i >= 0:
                break
            self._fill(more=1)
        inext = i + len(self._newline)
        line, self._buf = self._buf[:inext], self._buf[inext:]
        return line


def parse_http_message(kind, buf):
    if buf._end:
        return None
    try:
        start_line = buf.readline()
    except EOFError:
        return None
    msg = kind()
    msg.raw = start_line
    if kind is HttpRequest:
        assert re.match(
            br".+ HTTP/\d\.\d\r\n$", start_line
        ), "Start line does not look like HTTP request: " + repr(start_line)
        msg.method, msg.uri, msg.proto = start_line.rstrip().decode().split(" ", 2)
        assert msg.proto.startswith("HTTP/"), repr(start_line)
    elif kind is HttpResponse:
        assert re.match(
            br"^HTTP/\d\.\d \d+ .+\r\n$", start_line
        ), "Start line does not look like HTTP response: " + repr(start_line)
        msg.proto, msg.status, msg.reason = start_line.rstrip().decode().split(" ", 2)
        msg.status = int(msg.status)
        assert msg.proto.startswith("HTTP/"), repr(start_line)
    else:
        raise Exception("Use HttpRequest or HttpResponse .from_{bytes,buffered}")
    msg.version = msg.proto[5:]

    while True:
        line = buf.readline()
        msg.raw += line
        line = line.rstrip()
        if not line:
            break
        t = line.decode().split(":", 1)
        msg.headers[t[0].lower()] = t[1].lstrip()

    content_length_string = msg.headers.get("content-length", "")
    if content_length_string.isdigit():
        content_length = int(content_length_string)
        msg.body = msg.body_raw = buf.read(content_length)
    elif msg.headers.get("transfer-encoding") == "chunked":
        raise NotImplemented
    elif msg.version == "1.0":
        msg.body = msg.body_raw = buf.readall()
    else:
        msg.body = msg.body_raw = b""

    msg.raw += msg.body_raw
    return msg


class HttpMessage(object):
    def __init__(self):
        self.headers = {}

    @classmethod
    def from_bytes(cls, bs):
        buf = BufferedReader(bs)
        return parse_http_message(cls, buf)

    @classmethod
    def from_buffered(cls, buf):
        return parse_http_message(cls, buf)

    def __repr__(self):
        return "{} {}".format(self.__class__, repr(vars(self)))


class HttpRequest(HttpMessage):
    pass


class HttpResponse(HttpMessage):
    pass


class MockResponse(six.BytesIO):
    def __init__(self, body, **kwargs):
        six.BytesIO.__init__(self, body)
        self.headers = kwargs

    def items(self):
        return self.headers.items()

    def iteritems(self):
        return six.iteritems(self.headers)


class MockHTTPConnection(object):
    """This class is just a mock of httplib.HTTPConnection used for testing
    """

    def __init__(
        self,
        host,
        port=None,
        key_file=None,
        cert_file=None,
        strict=None,
        timeout=None,
        proxy_info=None,
    ):
        self.host = host
        self.port = port
        self.timeout = timeout
        self.log = ""
        self.sock = None

    def set_debuglevel(self, level):
        pass

    def connect(self):
        "Connect to a host on a given port."
        pass

    def close(self):
        pass

    def request(self, method, request_uri, body, headers):
        pass

    def getresponse(self):
        return MockResponse(b"the body", status="200")


class MockHTTPBadStatusConnection(object):
    """Mock of httplib.HTTPConnection that raises BadStatusLine.
    """

    num_calls = 0

    def __init__(
        self,
        host,
        port=None,
        key_file=None,
        cert_file=None,
        strict=None,
        timeout=None,
        proxy_info=None,
    ):
        self.host = host
        self.port = port
        self.timeout = timeout
        self.log = ""
        self.sock = None
        MockHTTPBadStatusConnection.num_calls = 0

    def set_debuglevel(self, level):
        pass

    def connect(self):
        pass

    def close(self):
        pass

    def request(self, method, request_uri, body, headers):
        pass

    def getresponse(self):
        MockHTTPBadStatusConnection.num_calls += 1
        raise http_client.BadStatusLine("")


@contextlib.contextmanager
def server_socket(fun, request_count=1, timeout=5, scheme="", tls=None):
    """Base socket server for tests.
    Likely you want to use server_request or other higher level helpers.
    All arguments except fun can be passed to other server_* helpers.

    :param fun: fun(client_sock, tick) called after successful accept().
    :param request_count: test succeeds after exactly this number of requests, triggered by tick(request)
    :param timeout: seconds.
    :param scheme: affects yielded value
        "" - build normal http/https URI.
        string - build normal URI using supplied scheme.
        None - yield (addr, port) tuple.
    :param tls:
        None (default) - plain HTTP.
        True - HTTPS with reasonable defaults. Likely you want httplib2.Http(ca_certs=tests.CA_CERTS)
        string - path to custom server cert+key PEM file.
        callable - function(context, listener, skip_errors) -> ssl_wrapped_listener
    """
    gresult = [None]
    gcounter = [0]
    tls_skip_errors = [
        "TLSV1_ALERT_UNKNOWN_CA",
    ]

    def tick(request):
        gcounter[0] += 1
        keep = True
        keep &= gcounter[0] < request_count
        if request is not None:
            keep &= request.headers.get("connection", "").lower() != "close"
        return keep

    def server_socket_thread(srv):
        try:
            while gcounter[0] < request_count:
                try:
                    client, _ = srv.accept()
                except ssl.SSLError as e:
                    if e.reason in tls_skip_errors:
                        return
                    raise

                try:
                    client.settimeout(timeout)
                    fun(client, tick)
                finally:
                    try:
                        client.shutdown(socket.SHUT_RDWR)
                    except (IOError, socket.error):
                        pass
                    # FIXME: client.close() introduces connection reset by peer
                    # at least in other/connection_close test
                    # should not be a problem since socket would close upon garbage collection
            if gcounter[0] > request_count:
                gresult[0] = Exception(
                    "Request count expected={0} actual={1}".format(
                        request_count, gcounter[0]
                    )
                )
        except Exception as e:
            # traceback.print_exc caused IOError: concurrent operation on sys.stderr.close() under setup.py test
            print(traceback.format_exc(), file=sys.stderr)
            gresult[0] = e

    bind_hostname = "localhost"
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((bind_hostname, 0))
    try:
        server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    except socket.error as ex:
        print("non critical error on SO_REUSEADDR", ex)
    server.listen(10)
    server.settimeout(timeout)
    server_port = server.getsockname()[1]
    if tls is True:
        tls = SERVER_CHAIN
    if tls:
        context = ssl_context()
        if callable(tls):
            context.load_cert_chain(SERVER_CHAIN)
            server = tls(context, server, tls_skip_errors)
        else:
            context.load_cert_chain(tls)
            server = context.wrap_socket(server, server_side=True)
    if scheme == "":
        scheme = "https" if tls else "http"

    t = threading.Thread(target=server_socket_thread, args=(server,))
    t.daemon = True
    t.start()
    if scheme is None:
        yield (bind_hostname, server_port)
    else:
        yield u"{scheme}://{host}:{port}/".format(scheme=scheme, host=bind_hostname, port=server_port)
    server.close()
    t.join()
    if gresult[0] is not None:
        raise gresult[0]


def server_yield(fun, **kwargs):
    q = queue.Queue(1)
    g = fun(q.get)

    def server_yield_socket_handler(sock, tick):
        buf = BufferedReader(sock)
        i = 0
        while True:
            request = HttpRequest.from_buffered(buf)
            if request is None:
                break
            i += 1
            request.client_sock = sock
            request.number = i
            q.put(request)
            response = six.next(g)
            sock.sendall(response)
            request.client_sock = None
            if not tick(request):
                break

    return server_socket(server_yield_socket_handler, **kwargs)


def server_request(request_handler, **kwargs):
    def server_request_socket_handler(sock, tick):
        buf = BufferedReader(sock)
        i = 0
        while True:
            request = HttpRequest.from_buffered(buf)
            if request is None:
                break
            # print("--- debug request\n" + request.raw.decode("ascii", "replace"))
            i += 1
            request.client_sock = sock
            request.number = i
            response = request_handler(request=request)
            # print("--- debug response\n" + response.decode("ascii", "replace"))
            sock.sendall(response)
            request.client_sock = None
            if not tick(request):
                break

    return server_socket(server_request_socket_handler, **kwargs)


def server_const_bytes(response_content, **kwargs):
    return server_request(lambda request: response_content, **kwargs)


_http_kwargs = (
    "proto",
    "status",
    "headers",
    "body",
    "add_content_length",
    "add_date",
    "add_etag",
    "undefined_body_length",
)


def http_response_bytes(
    proto="HTTP/1.1",
    status="200 OK",
    headers=None,
    body=b"",
    add_content_length=True,
    add_date=False,
    add_etag=False,
    undefined_body_length=False,
    **kwargs
):
    if undefined_body_length:
        add_content_length = False
    if headers is None:
        headers = {}
    if add_content_length:
        headers.setdefault("content-length", str(len(body)))
    if add_date:
        headers.setdefault("date", email.utils.formatdate())
    if add_etag:
        headers.setdefault("etag", '"{0}"'.format(hashlib.md5(body).hexdigest()))
    header_string = "".join("{0}: {1}\r\n".format(k, v) for k, v in headers.items())
    if (
        not undefined_body_length
        and proto != "HTTP/1.0"
        and "content-length" not in headers
    ):
        raise Exception(
            "httplib2.tests.http_response_bytes: client could not figure response body length"
        )
    if str(status).isdigit():
        status = "{} {}".format(status, http_client.responses[status])
    response = (
        "{proto} {status}\r\n{headers}\r\n".format(
            proto=proto, status=status, headers=header_string
        ).encode()
        + body
    )
    return response


def make_http_reflect(**kwargs):
    assert "body" not in kwargs, "make_http_reflect will overwrite response " "body"

    def fun(request):
        kw = copy.deepcopy(kwargs)
        kw["body"] = request.raw
        response = http_response_bytes(**kw)
        return response

    return fun


def server_route(routes, **kwargs):
    response_404 = http_response_bytes(status="404 Not Found")
    response_wildcard = routes.get("")

    def handler(request):
        target = routes.get(request.uri, response_wildcard) or response_404
        if callable(target):
            response = target(request=request)
        else:
            response = target
        return response

    return server_request(handler, **kwargs)


def server_const_http(**kwargs):
    response_kwargs = {k: kwargs.pop(k) for k in dict(kwargs) if k in _http_kwargs}
    response = http_response_bytes(**response_kwargs)
    return server_const_bytes(response, **kwargs)


def server_list_http(responses, **kwargs):
    i = iter(responses)

    def handler(request):
        return next(i)

    kwargs.setdefault("request_count", len(responses))
    return server_request(handler, **kwargs)


def server_reflect(**kwargs):
    response_kwargs = {k: kwargs.pop(k) for k in dict(kwargs) if k in _http_kwargs}
    http_handler = make_http_reflect(**response_kwargs)
    return server_request(http_handler, **kwargs)


def http_parse_auth(s):
    """https://tools.ietf.org/html/rfc7235#section-2.1
    """
    scheme, rest = s.split(" ", 1)
    result = {}
    while True:
        m = httplib2.WWW_AUTH_RELAXED.search(rest)
        if not m:
            break
        if len(m.groups()) == 3:
            key, value, rest = m.groups()
            result[key.lower()] = httplib2.UNQUOTE_PAIRS.sub(r"\1", value)
    return result


def store_request_response(out):
    def wrapper(fun):
        @functools.wraps(fun)
        def wrapped(request, *a, **kw):
            response_bytes = fun(request, *a, **kw)
            if out is not None:
                response = HttpResponse.from_bytes(response_bytes)
                out.append((request, response))
            return response_bytes

        return wrapped

    return wrapper


def http_reflect_with_auth(
    allow_scheme, allow_credentials, out_renew_nonce=None, out_requests=None
):
    """allow_scheme - 'basic', 'digest', etc allow_credentials - sequence of ('name', 'password') out_renew_nonce - None | [function]

        Way to return nonce renew function to caller.
        Kind of `out` parameter in some programming languages.
        Allows to keep same signature for all handler builder functions.
    out_requests - None | []
        If set to list, every parsed request will be appended here.
    """
    glastnc = [None]
    gnextnonce = [None]
    gserver_nonce = [gen_digest_nonce(salt=b"n")]
    realm = "httplib2 test"
    server_opaque = gen_digest_nonce(salt=b"o")

    def renew_nonce():
        if gnextnonce[0]:
            assert False, (
                "previous nextnonce was not used, probably bug in " "test code"
            )
        gnextnonce[0] = gen_digest_nonce()
        return gserver_nonce[0], gnextnonce[0]

    if out_renew_nonce:
        out_renew_nonce[0] = renew_nonce

    def deny(**kwargs):
        nonce_stale = kwargs.pop("nonce_stale", False)
        if nonce_stale:
            kwargs.setdefault("body", b"nonce stale")
        if allow_scheme == "basic":
            authenticate = 'basic realm="{realm}"'.format(realm=realm)
        elif allow_scheme == "digest":
            authenticate = (
                'digest realm="{realm}", qop="auth"'
                + ', nonce="{nonce}", opaque="{opaque}"'
                + (", stale=true" if nonce_stale else "")
            ).format(realm=realm, nonce=gserver_nonce[0], opaque=server_opaque)
        else:
            raise Exception("unknown allow_scheme={0}".format(allow_scheme))
        deny_headers = {"www-authenticate": authenticate}
        kwargs.setdefault("status", 401)
        # supplied headers may overwrite generated ones
        deny_headers.update(kwargs.get("headers", {}))
        kwargs["headers"] = deny_headers
        kwargs.setdefault("body", b"HTTP authorization required")
        return http_response_bytes(**kwargs)

    @store_request_response(out_requests)
    def http_reflect_with_auth_handler(request):
        auth_header = request.headers.get("authorization", "")
        if not auth_header:
            return deny()
        if " " not in auth_header:
            return http_response_bytes(
                status=400, body=b"authorization header syntax error"
            )
        scheme, data = auth_header.split(" ", 1)
        scheme = scheme.lower()
        if scheme != allow_scheme:
            return deny(body=b"must use different auth scheme")
        if scheme == "basic":
            decoded = base64.b64decode(data).decode()
            username, password = decoded.split(":", 1)
            if (username, password) in allow_credentials:
                return make_http_reflect()(request)
            else:
                return deny(body=b"supplied credentials are not allowed")
        elif scheme == "digest":
            server_nonce_old = gserver_nonce[0]
            nextnonce = gnextnonce[0]
            if nextnonce:
                # server decided to change nonce, in this case, guided by caller test code
                gserver_nonce[0] = nextnonce
                gnextnonce[0] = None
            server_nonce_current = gserver_nonce[0]
            auth_info = http_parse_auth(data)
            client_cnonce = auth_info.get("cnonce", "")
            client_nc = auth_info.get("nc", "")
            client_nonce = auth_info.get("nonce", "")
            client_opaque = auth_info.get("opaque", "")
            client_qop = auth_info.get("qop", "auth").strip('"')

            # TODO: auth_info.get('algorithm', 'md5')
            hasher = hashlib.md5

            # TODO: client_qop auth-int
            ha2 = hasher(":".join((request.method, request.uri)).encode()).hexdigest()

            if client_nonce != server_nonce_current:
                if client_nonce == server_nonce_old:
                    return deny(nonce_stale=True)
                return deny(body=b"invalid nonce")
            if not client_nc:
                return deny(body=b"auth-info nc missing")
            if client_opaque != server_opaque:
                return deny(
                    body="auth-info opaque mismatch expected={} actual={}".format(
                        server_opaque, client_opaque
                    ).encode()
                )
            for allow_username, allow_password in allow_credentials:
                ha1 = hasher(
                    ":".join((allow_username, realm, allow_password)).encode()
                ).hexdigest()
                allow_response = hasher(
                    ":".join(
                        (ha1, client_nonce, client_nc, client_cnonce, client_qop, ha2)
                    ).encode()
                ).hexdigest()
                rspauth_ha2 = hasher(":{}".format(request.uri).encode()).hexdigest()
                rspauth = hasher(
                    ":".join(
                        (
                            ha1,
                            client_nonce,
                            client_nc,
                            client_cnonce,
                            client_qop,
                            rspauth_ha2,
                        )
                    ).encode()
                ).hexdigest()
                if auth_info.get("response", "") == allow_response:
                    # TODO: fix or remove doubtful comment
                    # do we need to save nc only on success?
                    glastnc[0] = client_nc
                    allow_headers = {
                        "authentication-info": " ".join(
                            (
                                'nextnonce="{}"'.format(nextnonce) if nextnonce else "",
                                "qop={}".format(client_qop),
                                'rspauth="{}"'.format(rspauth),
                                'cnonce="{}"'.format(client_cnonce),
                                "nc={}".format(client_nc),
                            )
                        ).strip()
                    }
                    return make_http_reflect(headers=allow_headers)(request)
            return deny(body=b"supplied credentials are not allowed")
        else:
            return http_response_bytes(
                status=400,
                body="unknown authorization scheme={0}".format(scheme).encode(),
            )

    return http_reflect_with_auth_handler


def get_cache_path():
    default = "./_httplib2_test_cache"
    path = os.environ.get("httplib2_test_cache_path") or default
    if os.path.exists(path):
        shutil.rmtree(path)
    return path


def gen_digest_nonce(salt=b""):
    t = struct.pack(">Q", int(time.time() * 1e9))
    return base64.b64encode(t + b":" + hashlib.sha1(t + salt).digest()).decode()


def gen_password():
    length = random.randint(8, 64)
    return "".join(six.unichr(random.randint(0, 127)) for _ in range(length))


def gzip_compress(bs):
    # gzipobj = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16)
    # result = gzipobj.compress(text) + gzipobj.flush()
    buf = six.BytesIO()
    gf = gzip.GzipFile(fileobj=buf, mode="wb", compresslevel=6)
    gf.write(bs)
    gf.close()
    return buf.getvalue()


def gzip_decompress(bs):
    return zlib.decompress(bs, zlib.MAX_WBITS | 16)


def deflate_compress(bs):
    do = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS)
    return do.compress(bs) + do.flush()


def deflate_decompress(bs):
    return zlib.decompress(bs, -zlib.MAX_WBITS)


def ssl_context(protocol=None):
    """Workaround for old SSLContext() required protocol argument.
    """
    if sys.version_info < (3, 5, 3):
        return ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    return ssl.SSLContext()
