try:
    from keystoneclient.v2_0 import client as keystone_client
    from glance import client as glance_client
    from novaclient.v1_1 import client as nova_client
    from quantumclient.v2_0 import client as quantum_client
    from nova.db.sqlalchemy import api as nova_db_api 
    from nova.context import get_admin_context
    from keystone.common.sql import core  
    core.CONF(args=[], project='keystone', default_config_files=['/etc/keystone/keystone.conf'])
    from keystone.identity.backends.sql import Metadata
    has_openstack = True
except:
    has_openstack = False

from planetstack.config import Config
from deployment_auth import deployment_auth

def require_enabled(callable):
    def wrapper(*args, **kwds):
        if has_openstack:
            return callable(*args, **kwds)
        else:
            return None
    return wrapper

def parse_novarc(filename):
    opts = {}
    f = open(filename, 'r')
    for line in f:
        try:
            line = line.replace('export', '').strip()
            parts = line.split('=')
            if len(parts) > 1:
                value = parts[1].replace("\'", "")
                value = value.replace('\"', '')
                opts[parts[0]] = value
        except:
            pass
    f.close()
    return opts

class Client:
    def __init__(self, username=None, password=None, tenant=None, url=None, token=None, endpoint=None, deployment=None, *args, **kwds):
        
            
        if not deployment or deployment not in deployment_auth:
            auth = deployment_auth['default']
        else:
            auth = deployment_auth[deployment]
            
            
        self.has_openstack = has_openstack
        self.username = auth['user']
        self.password = auth['password']
        self.tenant = auth['tenant']
        self.url = auth['url']
        self.endpoint = auth['endpoint']
        self.token = auth['token']  

        if username:
            self.username = username
        if password:
            self.password = password
        if tenant:
            self.tenant = tenant
        if url:
            self.url = url
        if token:
            self.token = token    
        if endpoint:
            self.endpoint = endpoint

        #if '@' in self.username:
        #    self.username = self.username[:self.username.index('@')]

class KeystoneDB:
    @require_enabled
    def get_session(self):
        return core.Base().get_session()

    @require_enabled
    def get_metadata(self):
        session = self.get_session()
        return session.query(Metadata).all()     


class KeystoneClient(Client):
    def __init__(self, *args, **kwds):
        Client.__init__(self, *args, **kwds)
        if has_openstack:
            self.client = keystone_client.Client(username=self.username,
                                                 password=self.password,
                                                 tenant_name=self.tenant,
                                                 auth_url=self.url,
                                                 endpoint=self.endpoint,
                                                 token=self.token
                                                )

    @require_enabled
    def connect(self, *args, **kwds):
        self.__init__(*args, **kwds)

    @require_enabled
    def __getattr__(self, name):
        return getattr(self.client, name)


class GlanceClient(Client):
    def __init__(self, *args, **kwds):
        Client.__init__(self, *args, **kwds)
        if has_openstack:
            self.client = glance_client.get_client(host='0.0.0.0',
                                                   username=self.username,
                                                   password=self.password,
                                                   tenant=self.tenant,
                                                   auth_url=self.url)
    @require_enabled
    def __getattr__(self, name):
        return getattr(self.client, name)

class NovaClient(Client):
    def __init__(self, *args, **kwds):
        Client.__init__(self, *args, **kwds)
        if has_openstack:
            self.client = nova_client.Client(username=self.username,
                                             api_key=self.password,
                                             project_id=self.tenant,
                                             auth_url=self.url,
                                             region_name='',
                                             extensions=[],
                                             service_type='compute',
                                             service_name='',
                                             )

    @require_enabled
    def connect(self, *args, **kwds):
        self.__init__(*args, **kwds)

    @require_enabled
    def __getattr__(self, name):
        return getattr(self.client, name)

class NovaDB(Client):
    def __init__(self, *args, **kwds):
        Client.__init__(self, *args, **kwds)
        if has_openstack:
            self.ctx = get_admin_context()
            nova_db_api.FLAGS(default_config_files=['/etc/nova/nova.conf'])
            self.client = nova_db_api


    @require_enabled
    def connect(self, *args, **kwds):
        self.__init__(*args, **kwds)

    @require_enabled
    def __getattr__(self, name):
        return getattr(self.client, name)

class QuantumClient(Client):
    def __init__(self, *args, **kwds):
        Client.__init__(self, *args, **kwds)
        if has_openstack:
            self.client = quantum_client.Client(username=self.username,
                                                password=self.password,
                                                tenant_name=self.tenant,
                                                auth_url=self.url)
    @require_enabled
    def connect(self, *args, **kwds):
        self.__init__(*args, **kwds)

    @require_enabled
    def __getattr__(self, name):
        return getattr(self.client, name)

class OpenStackClient:
    """
    A simple native shell to the openstack backend services.
    This class can receive all nova calls to the underlying testbed
    """

    def __init__ ( self, *args, **kwds) :
        # instantiate managers
        self.keystone = KeystoneClient(*args, **kwds)
        self.keystone_db = KeystoneDB()
        self.glance = GlanceClient(*args, **kwds)
        self.nova = NovaClient(*args, **kwds)
        self.nova_db = NovaDB(*args, **kwds)
        self.quantum = QuantumClient(*args, **kwds)

    @require_enabled
    def connect(self, *args, **kwds):
        self.__init__(*args, **kwds)

    @require_enabled
    def authenticate(self):
        return self.keystone.authenticate()
