"""
Main entry point for application level plugins.

@todo handle multiple sgbds
"""
import argparse
import sys
import logging
import traceback
from sqlalchemy import create_engine
from find_plugins import find_cast_plugins, call_application_level_extensions, get_plugins
from cast.application import KnowledgeBase, create_postgres_engine, create_oracle_engine, create_sqlserver_engine
from cast.application.internal import set_current_application

def parse_arguments():

    parser = argparse.ArgumentParser()
    parser.add_argument('--log', help="output log file path", required=True)
    parser.add_argument('--application', help="application name")
    parser.add_argument('--castdirectory', help="CAIP installation directory")
    parser.add_argument('--event', help="event to trigger")
    parser.add_argument('--temporary', help="temporary folder for application")
    parser.add_argument('--intermediate', help="intermediate folder for application")

    parser.add_argument('--user', help="knowledge base connection user", default=None)
    parser.add_argument('--password', help="knowledge base connection password", default=None)
    parser.add_argument('--trusted', help="Use trusted connection for sqlserver", dest='trusted', action='store_true')
    parser.set_defaults(trusted=False)

    parser.add_argument('--database', help="knowledge base database type", choices=['postgresql', 'oracle', 'sqlserver'], default='postgresql')
    
    parser.add_argument('--host', help="knowledge base host")
    parser.add_argument('--port', help="knowledge base port", default=None, type=int)
    parser.add_argument('--instance', help="knowledge instance port", default=None)
    
    parser.add_argument('--sid', help="knowledge base sid (oracle)", default=None)
    parser.add_argument('--service', help="knowledge instance service", default=None)

    parser.add_argument('--schema', help="knowledge base name")

    return parser.parse_args()


def main():
    
    try:
        args = parse_arguments()
        
        file = open(args.log, 'w')
        file.write('Timestamp\a\tLevel\a\tTopic\a\tBody\a\tWho\a\tError Number\a\tRuntime File\a\tLine\a\tModule\a\tSource Line\a\tSource Column\a\tRuntime Context\a\tSource\n')
        file.close()
        
        FORMAT = ' %(asctime)-15s \a\t%(levelname)s\a\tMODULMSG ; Body\a\t%(message)s'
        logging.basicConfig(filename=args.log,
                            filemode='a+',
                            format=FORMAT,
                            level=logging.DEBUG)
        
        logging.info("Running Extensions at application level  ...")
        
        logging.info("Connecting to knowledge base ...")

        engine = None
        
        schema = args.schema
        
        if args.database == 'postgresql':
            engine = create_postgres_engine(args.user, args.password, args.host, args.port)
        elif args.database == 'oracle':
            engine = create_oracle_engine(args.user, args.password, args.host, args.port, args.sid, args.service)
        elif args.database == 'sqlserver':
            engine = create_sqlserver_engine(args.user, args.password, args.host, args.schema, args.port, args.instance, args.trusted)
            schema = None
        
        kb = KnowledgeBase(schema, engine=engine)
        application = kb.get_application(args.application)
        
        if not application:
            raise RuntimeError('Application %s does not exist. Existing applications are : %s' % (args.application, kb.get_applications()))
            
        set_current_application(application)
        
        logging.info("Connecting to knowledge base Done")

        find_cast_plugins(args.castdirectory, kb)
        plugins = get_plugins()

        # set lisa/ltsa
        for plugin in plugins:
            plugin.set_temporary(args.temporary)
            plugin.set_intermediate(args.intermediate)
       
        logging.debug("Marking extension jobs as unused ...")
        application._mark_plugin_jobs_as_unused()
        logging.debug("Marking extension jobs as unused Done")
        
        if plugins:
            call_application_level_extensions(args.event, application)

        logging.debug("Deleting unused job extension ...")
        application._delete_unused_jobs()
        logging.debug("Deleting unused job extension done")
            
        logging.info("Running Extensions at application level Done")
    
    except:
        logging.error("The following error occurred : %s",
                      traceback.format_exc())
        sys.exit(0)

main()
