# Copyright 2015 NEC Corporation.  All rights reserved.
#
#    Licensed 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.

from tempest_lib.common import rest_client
from tempest_lib import exceptions as lib_exceptions

from tempest import config
from tempest import exceptions

CONF = config.CONF


class ServiceClient(rest_client.RestClient):

    def __init__(self, auth_provider, service, region,
                 endpoint_type=None, build_interval=None, build_timeout=None,
                 disable_ssl_certificate_validation=None, ca_certs=None,
                 trace_requests=None):

        # TODO(oomichi): This params setting should be removed after all
        # service clients pass these values, and we can make ServiceClient
        # free from CONF values.
        dscv = (disable_ssl_certificate_validation or
                CONF.identity.disable_ssl_certificate_validation)
        params = {
            'disable_ssl_certificate_validation': dscv,
            'ca_certs': ca_certs or CONF.identity.ca_certificates_file,
            'trace_requests': trace_requests or CONF.debug.trace_requests
        }

        if endpoint_type is not None:
            params.update({'endpoint_type': endpoint_type})
        if build_interval is not None:
            params.update({'build_interval': build_interval})
        if build_timeout is not None:
            params.update({'build_timeout': build_timeout})
        super(ServiceClient, self).__init__(auth_provider, service, region,
                                            **params)

    def request(self, method, url, extra_headers=False, headers=None,
                body=None):
        # TODO(oomichi): This translation is just for avoiding a single
        # huge patch to migrate rest_client module to tempest-lib.
        # Ideally(in the future), we need to remove this translation and
        # replace each API tests with tempest-lib's exceptions.
        try:
            return super(ServiceClient, self).request(
                method, url,
                extra_headers=extra_headers,
                headers=headers, body=body)
        except lib_exceptions.BadRequest as ex:
            raise exceptions.BadRequest(ex)
        # TODO(oomichi): This is just a workaround for failing gate tests
        # when separating Forbidden from Unauthorized in tempest-lib.
        # We will need to remove this translation and replace negative tests
        # with lib_exceptions.Forbidden in the future.
        except lib_exceptions.Forbidden as ex:
            raise lib_exceptions.Unauthorized(ex)


class ResponseBody(dict):
    """Class that wraps an http response and dict body into a single value.

    Callers that receive this object will normally use it as a dict but
    can extract the response if needed.
    """

    def __init__(self, response, body=None):
        body_data = body or {}
        self.update(body_data)
        self.response = response

    def __str__(self):
        body = super.__str__(self)
        return "response: %s\nBody: %s" % (self.response, body)


class ResponseBodyData(object):
    """Class that wraps an http response and string data into a single value.
    """

    def __init__(self, response, data):
        self.response = response
        self.data = data

    def __str__(self):
        return "response: %s\nBody: %s" % (self.response, self.data)


class ResponseBodyList(list):
    """Class that wraps an http response and list body into a single value.

    Callers that receive this object will normally use it as a list but
    can extract the response if needed.
    """

    def __init__(self, response, body=None):
        body_data = body or []
        self.extend(body_data)
        self.response = response

    def __str__(self):
        body = super.__str__(self)
        return "response: %s\nBody: %s" % (self.response, body)
