"""Whisk Utility methods.

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
"""


import os
import json
import sys
if sys.version_info.major >= 3:
    from http.client import HTTPConnection, HTTPSConnection, IncompleteRead
    from urllib.parse import urlparse
else:
    from httplib import HTTPConnection, HTTPSConnection, IncompleteRead
    from urlparse import urlparse
import ssl
import base64
import socket


# global configurations, can control whether to allow untrusted certificates
# on HTTPS connections
httpRequestProps = {'secure': True}

def request(method, urlString, body = '', headers = {}, auth = None, verbose = False, https_proxy = os.getenv('https_proxy', None), timeout = 60):
    url = urlparse(urlString)
    if url.scheme == 'http':
        conn = HTTPConnection(url.netloc, timeout = timeout)
    else:
        if httpRequestProps['secure'] or not hasattr(ssl, '_create_unverified_context'):
            conn = HTTPSConnection(url.netloc if https_proxy is None else https_proxy, timeout = timeout)
        else:
            conn = HTTPSConnection(url.netloc if https_proxy is None else https_proxy, context=ssl._create_unverified_context(), timeout = timeout)
        if https_proxy:
            conn.set_tunnel(url.netloc)

    if auth is not None:
        auth = base64.b64encode(auth.encode()).decode()
        headers['Authorization'] = 'Basic %s' % auth

    if verbose:
        print('========')
        print('REQUEST:')
        print('%s %s' % (method, urlString))
        print('Headers sent:')
        print(getPrettyJson(headers))
        if body != '':
            print('Body sent:')
            print(body)

    try:
        conn.request(method, urlString, body, headers)
        res = conn.getresponse()
        body = ''
        try:
            body = res.read()
        except IncompleteRead as e:
            body = e.partial

        # patch the read to return just the body since the normal read
        # can only be done once
        res.read = lambda: body

        if verbose:
            print('--------')
            print('RESPONSE:')
            print('Got response with code %s' % res.status)
            print('Body received:')
            print(res.read())
            print('========')
        return res
    except socket.timeout:
        return ErrorResponse(status = 500, error = 'request timed out at %d seconds' % timeout)
    except Exception as e:
        return ErrorResponse(status = 500, error = str(e))


def getPrettyJson(obj):
    return json.dumps(obj, sort_keys=True, indent=4, separators=(',', ': '))


# class to normalize responses for exceptions with no HTTP response for canonical error handling
class ErrorResponse:
    def __init__(self, status, error):
        self.status = status
        self.error = error

    def read(self):
        return self.error
