"""Debug Plugin for EasyEngine."""

from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from ee.core.shellexec import EEShellExec
from ee.core.mysql import EEMysql
import os


def debug_plugin_hook(app):
    # do something with the ``app`` object here.
    pass


class EEDebugController(CementBaseController):
    class Meta:
        label = 'debug'
        description = 'debug command enables/disbaled stack debug'
        stacked_on = 'base'
        stacked_type = 'nested'
        arguments = [
            (['--stop'],
                dict(help='Stop debug', action='store_true')),
            (['--start'],
                dict(help='Start debug', action='store_true')),
            (['--nginx'],
                dict(help='Debug Nginx', action='store_true')),
            (['--php'],
                dict(help='Debug PHP', action='store_true')),
            (['--fpm'],
                dict(help='Debug FastCGI', action='store_true')),
            (['--mysql'],
                dict(help='Debug MySQL', action='store_true')),
            (['--wp'],
                dict(help='Debug WordPress sites', action='store_true')),
            (['--rewrite'],
                dict(help='Debug Nginx rewrite rules', action='store_true')),
            (['-i', '--interactive'],
                dict(help='Interactive debug', action='store_true')),
            (['--import-slow-log-interval'],
                dict(help='Import MySQL slow log to Anemometer',
                     action='store', dest='interval')),
            (['site_name'],
                dict(help='Website Name', nargs='?', default=None))
            ]

    @expose(hide=True)
    def debug_nginx(self):
        self.trigger_nginx = False
        # start global debug
        if self.start and not self.app.pargs.site_name:
            try:
                debug_address = (self.app.config.get('stack', 'ip-address')
                                 .split())
            except Exception as e:
                debug_address = ['0.0.0.0/0']
            for ip_addr in debug_address:
                if not ("debug_connection "+ip_addr in open('/etc/nginx/'
                   'nginx.conf').read()):
                    print("Setting up NGINX debug connection for "+ip_addr)
                    EEShellExec.cmd_exec(self, "sed -i \"/events {{/a\\ \\ \\ "
                                               "\\ $(echo debug_connection "
                                               "{ip}\;)\" /etc/nginx/"
                                               "nginx.conf".format(ip=ip_addr))
                    self.trigger_nginx = True

            if not self.trigger_nginx:
                print("NGINX debug connection already enabled")

            self.msg = self.msg + " /var/log/nginx/*.error.log"

        # stop global debug
        elif not self.start and not self.app.pargs.site_name:
            if "debug_connection " in open('/etc/nginx/nginx.conf').read():
                print("Disabling Nginx debug connections")
                EEShellExec.cmd_exec(self, "sed -i \"/debug_connection.*/d\""
                                     " /etc/nginx/nginx.conf")
                self.trigger_nginx = True
            else:
                print("Nginx debug connection already disbaled")

        # start site specific debug
        elif self.start and self.app.pargs.site_name:
            config_path = ("/etc/nginx/sites-available/{0}"
                           .format(self.app.pargs.site_name))
            if os.path.isfile(config_path):
                if not EEShellExec.cmd_exec("grep \"error.log debug\" {0}"
                                            .format(config_path)):
                    print("Starting NGINX debug connection for {0}"
                          .format(self.app.pargs.site_name))
                    EEShellExec.cmd_exec("sed -i \"s/error.log;/error.log "
                                         "debug;/\" {0}".format(config_path))
                    self.trigger_nginx = True

                else:
                    print("Debug for site allready enabled")

            else:
                print("{0} domain not valid".format(self.app.pargs.site_name))

        # stop site specific debug
        elif not self.start and self.app.pargs.site_name:
            config_path = ("/etc/nginx/sites-available/{0}"
                           .format(self.app.pargs.site_name))
            if os.path.isfile(config_path):
                if EEShellExec.cmd_exec("grep \"error.log debug\" {0}"
                                        .format(config_path)):
                    print("Stoping NGINX debug connection for {0}"
                          .format(self.app.pargs.site_name))
                    EEShellExec.cmd_exec("sed -i \"s/error.log debug;/"
                                         "error.log;/\" {0}"
                                         .format(config_path))
                    self.trigger_nginx = True

                else:
                    print("Debug for site allready disbaled")

            else:
                print("{0} domain not valid".format(self.app.pargs.site_name))

    @expose(hide=True)
    def debug_php(self):
        # PHP global debug start
        if self.start:
            if not (EEShellExec.cmd_exec(self, "sed -n \"/upstream php"
                                               "{/,/}/p \" /etc/nginx/"
                                               "conf.d/upstream.conf "
                                               "| grep 9001")):
                print("Enabling PHP debug")
                data = dict(php="9001", debug="9001")
                self.app.log.debug('writting the nginx configration to file'
                                   '/etc/nginx/conf.d/upstream.conf ')
                ee_nginx = open('/etc/nginx/conf.d/upstream.conf', 'w')
                self.app.render((data), 'upstream.mustache', out=ee_nginx)
                ee_nginx.close()
                self.trigger_php = True
            else:
                print("PHP debug is allready enabled")

        # PHP global debug stop
        else:
            if EEShellExec.cmd_exec(self, "sed -n \"/upstream php {/,/}/p\" "
                                          "/etc/nginx/conf.d/upstream.conf "
                                          "| grep 9001"):
                print("Disabling PHP debug")
                data = dict(php="9000", debug="9001")
                self.app.log.debug('writting the nginx configration to file'
                                   '/etc/nginx/conf.d/upstream.conf ')
                ee_nginx = open('/etc/nginx/conf.d/upstream.conf', 'w')
                self.app.render((data), 'upstream.mustache', out=ee_nginx)
                ee_nginx.close()
                self.trigger_php = True
            else:
                print("PHP debug is allready disbaled")

    @expose(hide=True)
    def debug_fpm(self):
        # PHP5-FPM start global debug
        if self.start:
            if not EEShellExec.cmd_exec(self, "grep \"log_level = debug\" "
                                              "/etc/php5/fpm/php-fpm.conf"):
                print("Setting up PHP5-FPM log_level = debug")
                EEShellExec.cmd_exec(self, "sed -i \"s\';log_level.*\'log_"
                                           "level = debug\'\" /etc/php5/fpm"
                                           "/php-fpm.conf")
                self.trigger_php = True
            else:
                print("PHP5-FPM log_level = debug already setup")
        # PHP5-FPM stop global debug
        else:
            if EEShellExec.cmd_exec(self, "grep \"log_level = debug\" "
                                          "/etc/php5/fpm/php-fpm.conf"):
                print("Disabling PHP5-FPM log_level = debug")
                EEShellExec.cmd_exec(self, "sed -i \"s\'log_level.*\';log_"
                                           "level = notice\'\" /etc/php5/fpm"
                                           "/php-fpm.conf")
                self.trigger_php = True
            else:
                print("PHP5-FPM log_level = debug already disabled")

    @expose(hide=True)
    def debug_mysql(self):
        # MySQL start global debug
        if self.start:
            if not EEShellExec.cmd_exec(self, "mysql -e \"show variables like"
                                              " \'slow_query_log\';\" | "
                                              "grep ON"):
                print("Setting up MySQL slow log")
                EEMysql.execute(self, "set global slow_query_log = "
                                      "\'ON\';")
                EEMysql.execute(self, "set global slow_query_log_file = "
                                      "\'/var/log/mysql/mysql-slow.log\';")
                EEMysql.execute(self, "set global long_query_time = 2;")
                EEMysql.execute(self, "set global log_queries_not_using"
                                      "_indexes = \'ON\';")
                if self.app.pargs.interval:
                    try:
                        cron_time = int(self.app.pargs.interval)
                    except Exception as e:
                        cron_time = 5
                    EEShellExec.cmd_exec(self, "/bin/bash -c \"crontab -l 2> "
                                         "/dev/null | {{ cat; echo -e"
                                         " \\\"#EasyEngine start MySQL slow"
                                         " log \\n*/{0} * * * * "
                                         "/usr/local/sbin/ee import-slow-log\\"
                                         "n#EasyEngine end MySQL slow log\\\";"
                                         " }} | crontab -\"".format(cron_time))
            else:
                print("MySQL slow log is allready enabled")
        # MySQL stop global debug
        else:
            if EEShellExec.cmd_exec(self, "mysql -e \"show variables like \'"
                                    "slow_query_log\';\" | grep ON"):
                print("Disabling MySQL slow log")
                EEMysql.execute(self, "set global slow_query_log = \'OFF\';")
                EEMysql.execute(self, "set global slow_query_log_file = \'"
                                "/var/log/mysql/mysql-slow.log\';")
                EEMysql.execute(self, "set global long_query_time = 10;")
                EEMysql.execute(self, "set global log_queries_not_using_index"
                                "es = \'OFF\';")
                EEShellExec.cmd_exec(self, "crontab -l | sed \'/#EasyEngine "
                                     "start/,/#EasyEngine end/d\' | crontab -")
            else:
                print("MySQL slow log already disabled")

    @expose(hide=True)
    def debug_wp(self):
        if self.start and self.app.pargs.site_name:
            wp_config = ("/var/www/{0}/wp-config.php"
                         .format(self.app.pargs.site_name))
            webroot = "/var/www/{0}".format(self.app.pargs.site_name)
            if os.path.isfile(wp_config):
                if not EEShellExec.cmd_exec(self, "grep \"\'WP_DEBUG\'\" {0} |"
                                            " grep true".format(wp_config)):
                    print("Starting WordPress debug")
                    open("{0}/htdocs/wp-content/debug.log".format(webroot),
                         'a').close()
                    EEShellExec.cmd_exec(self, "chown www-data: {0}/htdocs/wp-"
                                         "content/debug.log".format(webroot))
                    EEShellExec.cmd_exec(self, "sed -i \"s/define(\'WP_DEBUG\'"
                                         ".*/define(\'WP_DEBUG\', true);\\n"
                                         "define(\'WP_DEBUG_DISPLAY\', false);"
                                         "\\ndefine(\'WP_DEBUG_LOG\', true);"
                                         "\\ndefine(\'SAVEQUERIES\', true);/\""
                                         " {0}".format(wp_config))
                    EEShellExec.cmd_exec(self, "cd {0}/htdocs/ && wp"
                                         " plugin --allow-root install "
                                         "developer".format(webroot))
                    EEShellExec.cmd_exec(self, "chown -R www-data: {0}/htdocs/"
                                         "wp-content/plugins"
                                         .format(webroot))
                else:
                    print("WordPress debug log already enabled")
            else:
                print("{0} domain not valid".format(self.app.pargs.site_name))

        elif not self.start and self.app.pargs.site_name:
            wp_config = ("/var/www/{0}/wp-config.php"
                         .format(self.app.pargs.site_name))
            webroot = "/var/www/{0}".format(self.app.pargs.site_name)
            if os.path.isfile(wp_config):
                if EEShellExec.cmd_exec(self, "grep \"\'WP_DEBUG\'\" {0} | "
                                        "grep true".format(wp_config)):
                    print("Disabling WordPress debug")
                    EEShellExec.cmd_exec(self, "sed -i \"s/define(\'WP_DEBUG\'"
                                         ", true);/define(\'WP_DEBUG\', "
                                         "false);/\" {0}".format(wp_config))
                    EEShellExec.cmd_exec(self, "sed -i \"/define(\'"
                                         "WP_DEBUG_DISPLAY\', false);/d\" {0}"
                                         .format(wp_config))
                    EEShellExec.cmd_exec(self, "sed -i \"/define(\'"
                                         "WP_DEBUG_LOG\', true);/d\" {0}"
                                         .format(wp_config))
                    EEShellExec.cmd_exec("sed -i \"/define(\'"
                                         "SAVEQUERIES\', "
                                         "true);/d\" {0}".format(wp_config))
                else:
                    print("WordPress debug all already disbaled")
            else:
                print("{0} domain not valid".format(self.app.pargs.site_name))
        else:
            print("Missing argument site_name")

    @expose(hide=True)
    def debug_rewrite(self):
        if self.start and not self.app.pargs.site_name:
            print("Start WP-Rewrite debug globally")
        elif self.start and not self.app.pargs.site_name:
            print("Stop WP-Rewrite debug globally")
        elif self.start and self.app.pargs.site_name:
            print("Start WP-Rewrite for site")
        elif not self.start and not self.app.pargs.site_name:
            print("Stop WP-Rewrite for site")

    @expose(hide=True)
    def default(self):
        self.start = True
        self.interactive = False
        self.msg = ""

        if self.app.pargs.stop:
            self.start = False

        if ((not self.app.pargs.nginx) and (not self.app.pargs.php)
           and (not self.app.pargs.fpm) and (not self.app.pargs.mysql)
           and (not self.app.pargs.wp) and (not self.app.pargs.rewrite)):
            self.debug_nginx()
            self.debug_php()
            self.debug_fpm()
            self.debug_mysql()
            self.debug_wp()
            self.debug_rewrite()

        if self.app.pargs.nginx:
            self.debug_nginx()
        if self.app.pargs.php:
            self.debug_php()
        if self.app.pargs.fpm:
            self.debug_fpm()
        if self.app.pargs.mysql:
            self.debug_mysql()
        if self.app.pargs.wp:
            self.debug_wp()
        if self.app.pargs.rewrite:
            self.debug_rewrite()

        if self.app.pargs.interactive:
            self.interactive = True


def load(app):
    # register the plugin class.. this only happens if the plugin is enabled
    handler.register(EEDebugController)
    # register a hook (function) to run after arguments are parsed.
    hook.register('post_argument_parsing', debug_plugin_hook)