
import os

import flask
import glanceclient
from keystoneclient.v2_0 import client as keystoneclient

import signals

from . import Storage
from .local import LocalStorage
from .s3 import S3Storage
from .swift import SwiftStorage


class GlanceStorage(object):

    """This class is a dispatcher, it forwards methods accessing repositories
       to the alternate storage defined in the config and it forwards methods
       accessing images to the GlanceStorageLayers class below.
    """

    def __init__(self, config):
        self._config = config
        self._storage_layers = GlanceStorageLayers(config)
        kind = config.get('storage_alternate', 'local')
        self._storage_base = Storage()
        if kind == 's3':
            self._storage_tags = S3Storage(config)
        elif kind == 'local':
            self._storage_tags = LocalStorage(config)
        elif kind == 'swift':
            self._storage_tags = SwiftStorage(config)
        else:
            raise ValueError('Not supported storage \'{0}\''.format(kind))

    def _resolve_class_path(self, method_name, *args, **kwargs):
        path = ''
        if 'path' in kwargs:
            path = kwargs['path']
        elif len(args) > 0 and isinstance(args[0], basestring):
            path = args[0]
        if path.startswith(Storage.images):
            obj = self._storage_layers
        elif path.startswith(Storage.repositories):
            obj = self._storage_tags
        else:
            obj = self._storage_layers
        if not hasattr(obj, method_name):
            return
        return getattr(obj, method_name)

    def __getattr__(self, name):
        def dispatcher(*args, **kwargs):
            attr = self._resolve_class_path(name, *args, **kwargs)
            if not attr:
                raise ValueError('Cannot dispath method '
                                 '"{0}" args: {1}, {2}'.format(name,
                                                               args,
                                                               kwargs))
            if callable(attr):
                return attr(*args, **kwargs)
            return attr
        return dispatcher


class GlanceStorageLayers(Storage):

    """This class stores the image layers into OpenStack Glance.
       However tags are still stored on other filesystem-like stores.
    """