#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# This program runs warden module specified in command line
#

import os
import atexit
from warden.utils.log import Log
from warden.utils.config import Config
from warden.utils.db import DB
from warden.misc.common import is_vm
from warden.misc.path import DB_PATH, LOG_PATH, HW_WATCHER_CONF, CONF_PATH
from optparse import OptionParser

from operator import attrgetter

_version = "0.2.51"

if __name__ == '__main__':
    cwd = os.path.dirname(__file__)

    usage = "usage: %prog [options] command action"
    version = "%prog {0}".format(_version)
    parser = OptionParser(usage=usage, version=version)
    parser.add_option("-c", "--config", metavar="CONFIGFILE", dest="config",
        help="config file (default: %default)", default=os.path.join(HW_WATCHER_CONF, 'hw_watcher.conf'))
    parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
        help="verbose mode (default: %default)", default=False)
    parser.add_option("-i", "--ignore-vm", dest="ignore_vm", action="store_true",
        help="run even if inside a Virtual Machine (default: %default)", default=False)
    options, args = parser.parse_args()
    if not os.path.isabs(options.config):
        options.config = os.path.join(cwd, options.config)

    if len(args) < 2:
        parser.print_help()
        exit(2)
    command = args.pop(0)
    action = args.pop(0)

    config = Config(config=[options.config,
        os.path.join(CONF_PATH, '{0}.conf'.format(command)),
        os.path.join(os.path.dirname(os.path.realpath(__file__)), 'hw_watcher.conf')])

    log_path = config.get('global', 'log_path', LOG_PATH)
    log = Log('', log_path=os.path.join(log_path, '%s.log' % command), verbose=options.verbose).logger
    log.debug("Started")

    @atexit.register
    def log_exit():
        log.debug("Exited")

    inside_a_vm = is_vm()
    if inside_a_vm is None:
        log.warning("Can't determinate if running inside a VM. This is probably bug.")
    elif inside_a_vm and not options.ignore_vm:
        log.critical("VM detected: [ {0} ] and no --ignore-vm is given. Exiting.".format(inside_a_vm))
        exit(0)

    db_path = config.get('global', 'db_path', DB_PATH)
    config.db = DB(os.path.join(db_path, '%s.db' % command), force=True)

    try:
        # Import module for specified command
        module = __import__('warden.{0}.{0}'.format(command), globals(), locals(), ['*'])
    except Exception:
        log.critical("Failed to import module corresponding to command: {0}".format(command))
        exit(2)
    try:
        # We are trying to find method corresponding to action
        if not hasattr(module, action):
            log.critical("Unknown action passed to plugin {0}: {1}".format(command, action))
            parser.print_help()
            module.usage()
            exit(2)

        # If found run it with arguments
        ret = attrgetter(action)(module)(config, *args)
        # Pass exit code to os, depending on the value type returned by warden module
        if isinstance(ret, bool):
            exit(not ret)
        elif isinstance(ret, int):
            exit(ret)
        else:
            try:
                # TODO(rbtz@): Should we print it on console?
                exit(len(ret))
            except Exception:
                # Some objects like None does not have an len
                exit(0)
    except Exception:
        log.exception("Failed to preform action [ {0} ]. ".format(action))
        log.critical("It's probably a bug.")
        log.critical("You should contact rbtz@")
        exit(1)
