from storage.local import LocalStorage
from storage.cloud import S3Storage, GoogleCloudStorage, RadosGWStorage
from storage.fakestorage import FakeStorage
from storage.distributedstorage import DistributedStorage
from storage.swift import SwiftStorage
from storage.downloadproxy import DownloadProxy

from urlparse import urlparse, parse_qs

STORAGE_DRIVER_CLASSES = {
  'LocalStorage': LocalStorage,
  'S3Storage': S3Storage,
  'GoogleCloudStorage': GoogleCloudStorage,
  'RadosGWStorage': RadosGWStorage,
  'SwiftStorage': SwiftStorage,
}

def get_storage_driver(location, metric_queue, chunk_cleanup_queue, storage_params):
  """ Returns a storage driver class for the given storage configuration
      (a pair of string name and a dict of parameters). """
  driver = storage_params[0]
  parameters = storage_params[1]
  driver_class = STORAGE_DRIVER_CLASSES.get(driver, FakeStorage)
  context = StorageContext(location, metric_queue, chunk_cleanup_queue)
  return driver_class(context, **parameters)


class StorageContext(object):
  def __init__(self, location, metric_queue, chunk_cleanup_queue):
    self.location = location
    self.metric_queue = metric_queue
    self.chunk_cleanup_queue = chunk_cleanup_queue


class Storage(object):
  def __init__(self, app=None, metric_queue=None, chunk_cleanup_queue=None, instance_keys=None):
    self.app = app
    if app is not None:
      self.state = self.init_app(app, metric_queue, chunk_cleanup_queue, instance_keys)
    else:
      self.state = None

  def init_app(self, app, metric_queue, chunk_cleanup_queue, instance_keys):
    storages = {}
    for location, storage_params in app.config.get('DISTRIBUTED_STORAGE_CONFIG').items():
      storages[location] = get_storage_driver(location, metric_queue, chunk_cleanup_queue,
                                              storage_params)

    preference = app.config.get('DISTRIBUTED_STORAGE_PREFERENCE', None)
    if not preference:
      preference = storages.keys()

    default_locations = app.config.get('DISTRIBUTED_STORAGE_DEFAULT_LOCATIONS') or []

    download_proxy = None
    if app.config.get('FEATURE_PROXY_STORAGE', False) and instance_keys is not None:
      download_proxy = DownloadProxy(app, instance_keys)

    d_storage = DistributedStorage(storages, preference, default_locations, download_proxy)

    # register extension with app
    app.extensions = getattr(app, 'extensions', {})
    app.extensions['storage'] = d_storage
    return d_storage

  def __getattr__(self, name):
    return getattr(self.state, name, None)