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


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

def get_storage_driver(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)
  return driver_class(**parameters)


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

  def init_app(self, app):
    storages = {}
    for location, storage_params in app.config.get('DISTRIBUTED_STORAGE_CONFIG').items():
      storages[location] = get_storage_driver(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 []
    d_storage = DistributedStorage(storages, preference, default_locations)

    # 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)