# Copyright (c) 2010-2011 OpenStack, LLC.
#
# 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.

import webob
from urllib import quote, unquote
from json import loads as json_loads
import copy

from slogging.compressing_file_reader import CompressingFileReader
from swift.proxy.server import BaseApplication


class MemcacheStub(object):

    def get(self, *a, **kw):  # pragma: no cover
        return None

    def set(self, *a, **kw):  # pragma: no cover
        return None

    def incr(self, *a, **kw):  # pragma: no cover
        return 0

    def delete(self, *a, **kw):  # pragma: no cover
        return None

    def set_multi(self, *a, **kw):  # pragma: no cover
        return None

    def get_multi(self, *a, **kw):  # pragma: no cover
        return []


def make_request_body_file(source_file, compress=True):
    if hasattr(source_file, 'seek'):
        source_file.seek(0)
    else:
        source_file = open(source_file, 'rb')
    if compress:
        compressed_file = CompressingFileReader(source_file)
        return compressed_file
    return source_file


def webob_request_copy(orig_req, source_file=None, compress=True):
    req_copy = orig_req.copy()
    req_copy.headers = dict(orig_req.headers)
    if source_file:
        req_copy.body_file = make_request_body_file(source_file,
                                                    compress=compress)
    return req_copy


class InternalProxy(object):
    """
    Set up a private instance of a proxy server that allows normal requests
    to be made without having to actually send the request to the proxy.
    This also doesn't log the requests to the normal proxy logs.

    :param proxy_server_conf: proxy server configuration dictionary
    :param logger: logger to log requests to
    :param retries: number of times to retry each request
    """

    def __init__(self, proxy_server_conf=None, logger=None, retries=0):
        self.upload_app = BaseApplication(proxy_server_conf,
                                          memcache=MemcacheStub(),
                                          logger=logger)
        self.retries = retries

    def _handle_request(self, req, source_file=None, compress=True):
        req = self.upload_app.update_request(req)
        req_copy = webob_request_copy(req, source_file=source_file,
                                      compress=compress)
        resp = self.upload_app.handle_request(req_copy)
        tries = 1
        while (resp.status_int < 200 or resp.status_int > 299) \
                and tries < self.retries:
            req_copy = webob_request_copy(req, source_file=source_file,
                                          compress=compress)
            resp = self.upload_app.handle_request(req_copy)
            tries += 1
        return resp

    def upload_file(self, source_file, account, container, object_name,