import types
import textwrap
from docopt import docopt
import inspect
import sys
import importlib
import json
from pprint import pprint
from cmd3.shell import command
from cloudmesh.config.cm_keys import cm_keys_yaml,cm_keys_mongo
from cloudmesh.cm_mongo import cm_mongo
from cloudmesh_common.logger import LOGGER
from cloudmesh_common.tables import two_column_table

log = LOGGER(__file__)


class cm_shell_keys:

    """opt_example class."""

    def activate_shell_keys(self):

        self.mongo_loaded = False
        self.keys_loaded = False
        self.keys_loaded_mongo = False
        self.use_yaml = True
        self.register_command_topic('cloud','keys')
        pass

    def _load_mongo(self):
        if not self.mongo_loaded:
            try:
                self.mongoClass = cm_mongo()
                self.mongo_loaded = True
            except:
                print "ERROR: could not access Mongodb. " \
                      "Have you started the mongo server?"
    def _load_keys(self):
        try:
            filename = "$HOME/.futuregrid/cloudmesh.yaml"
            if self.echo:
                log.info("Reading keys information from -> {0}"
                         .format(filename))
            self.keys = cm_keys_yaml(filename)
            self.keys_loaded = True
        except:
            print "ERROR: could not find the keys in %s" % filename
    def _load_keys_mongo(self):
        #try:
        from cloudmesh.config.cm_config import cm_config
        config = cm_config()
        self.user = config.get('cloudmesh.profile.username')
                
        if self.echo:
            log.info("Reading keys information from -> mongo")
        self.keys_mongo = cm_keys_mongo(self.user)
        self.keys_loaded_mongo = True
        #except:
        #   print "ERROR: could not find the keys in %s" % filename


    @command
    def do_keys(self, args, arguments):
        """
        Usage:
               keys info [--json] [NAME][--yaml][--mongo]
               keys mode MODENAME               
               keys default NAME [--yaml][--mongo]
               keys add NAME KEY [--yaml][--mongo]
               keys delete NAME [--yaml][--mongo]
               keys persist
    
        Manages the keys

        Arguments:

          NAME           The name of a key
          MODENAME       This is used to specify the mode name. Mode name can be either 'yaml' or 'mongo'
          KEY            This is the actual key that has to added

        Options:

           -v --verbose     verbose mode
           -j --json        json output
           -y --yaml        forcefully use yaml mode
           -m --mongo       forcefully use mongo mode           

        Description:
 
        keys info 

	     Prints list of keys. NAME of the key can be specified

        keys mode MODENAME

	     Used to change default mode. Valid MODENAMES are
	     yaml(default) and mongo mode.

        keys default NAME

	     Used to set a key from the key-list as the default key

        keys add NAME KEY

	     adding/updating keys. Please provide filename and not the
	     actual key

        keys delete NAME

	     deletes a key. In yaml mode it can delete only keys that
	     are not persisted

        keys persist

	     Saves the temporary yaml data structure to mongo
        """
        if arguments["mode"]:
            if arguments["MODENAME"] == "yaml":
                self.use_yaml = True
                print "SUCCESS: Set mode to yaml"
                return
            elif arguments["MODENAME"] == "mongo":
                self.use_yaml = False
                print "SUCCESS: Set mode to mongo"
                return
            else:
                print "ERROR: Wrong MODENAME. only valid modes are 'mongo' and 'yaml'" 
                return

        if arguments["--yaml"] and arguments["--mongo"]:
           print "ERROR: you can specify only one mode"
           return
        elif arguments["--yaml"]:
           self.use_yaml = True
        elif arguments["--mongo"]:     
           self.use_yaml = False

        if self.use_yaml:
            print "Mode: yaml"
            if not self.keys_loaded:
                self._load_keys()
            key_container = self.keys
        else:
            print "Mode: mongo"
            if not self.mongo_loaded:
                self._load_mongo()
            if not self.keys_loaded_mongo:
                self._load_keys_mongo()
            key_container = self.keys_mongo
    
        if arguments["default"] and arguments["NAME"]:     
            if arguments["NAME"] in key_container.names():
                key_container.setdefault(arguments["NAME"])
                # Update mongo db defaults with new default key
                print 'The default key is set to: ', arguments['NAME']
            else:
                print "ERROR: Specified key is not registered."
            return

        if arguments["add"]:
            print "Attempting to add key..."
            key_container.__setitem__(arguments["NAME"],arguments["KEY"])
            return

        if arguments["delete"]:
            print "Attempting to delete key. {0}".format(arguments["NAME"])
            if self.use_yaml:
                print "WARNING: This will only remove the keys that have not been written to the databse\
already when 'keys persist' is called. If your key is already in the database, \
you should use mongo mode\n"
            key_container.delete(arguments["NAME"])
            return 
        if arguments["persist"]:
            if not self.mongo_loaded:
                self._load_mongo()
            if not self.keys_loaded_mongo:
                self._load_keys_mongo()
            key_mongo = self.keys_mongo
            key_yaml = self.keys
            names = key_yaml.names()    
            for name in names:
                key_mongo.__setitem__(name, key_yaml._getvalue(name),key_type="string")
            key_mongo.setdefault(key_yaml.get_default_key())
            return

        if (arguments["info"]) or (args==""):
            if arguments["--json"]:
                if arguments["NAME"] is None:
                    name = "keys"
                else: 
                    name = arguments["NAME"]
                try:
                    print json.dumps(key_container[name], indent=4)
                except:
                    print "ERROR: Something went wrong in looking up keys. Did u give the right name??"    
                return
            else:
                mykeys = {}
                header = ["Default", "Fingerprint"]
                try:
                    mykeys["default"] = key_container.get_default_key()
                except:
                    mykeys["default"] = "default is not set, please set it"
                for name in key_container.names():
                    mykeys[name] = key_container.fingerprint(name)
                print two_column_table(mykeys)
                return
        

if __name__ == '__main__':
    arguments = {}
    arguments['mode'] = True
    arguments['MODENAME'] = "yaml"
    

@@ -2376,16 +2376,22 @@
 me. Mode
+%0A%09  %09%09
  name ca
@@ -2420,16 +2420,17 @@
 'mongo'%0A
+%0A
         

format doc