"""
Simple example for a user-defined service.
"""

from core.services.coreservices import CoreService
from core.services.coreservices import ServiceMode


class HaproxyService(CoreService):
    """
    Custom CORE Service

    :var str name: name used as a unique ID for this service and is required, no spaces
    :var str group: allows you to group services within the GUI under a common name
    :var tuple executables: executables this service depends on to function, if executable is
        not on the path, service will not be loaded
    :var tuple dependencies: services that this service depends on for startup, tuple of service names
    :var tuple dirs: directories that this service will create within a node
    :var tuple configs: files that this service will generate, without a full path this file goes in
        the node's directory e.g. /tmp/pycore.12345/n1.conf/myfile
    :var tuple startup: commands used to start this service, any non-zero exit code will cause a failure
    :var tuple validate: commands used to validate that a service was started, any non-zero exit code
        will cause a failure
    :var ServiceMode validation_mode: validation mode, used to determine startup success.
        NON_BLOCKING    - runs startup commands, and validates success with validation commands
        BLOCKING        - runs startup commands, and validates success with the startup commands themselves
        TIMER           - runs startup commands, and validates success by waiting for "validation_timer" alone
    :var int validation_timer: time in seconds for a service to wait for validation, before determining
        success in TIMER/NON_BLOCKING modes.
    :var float validation_validation_period: period in seconds to wait before retrying validation,
        only used in NON_BLOCKING mode
    :var tuple shutdown: shutdown commands to stop this service
    """
    name = "Haproxy"
    group = "Utility"
    executables = ()
    dependencies = ()
    dirs = ("/etc/haproxy",)
    configs = ("haproxy.sh", "/etc/haproxy/haproxy.conf",)
    validation_mode = ServiceMode.NON_BLOCKING
    startup = ("bash haproxy.sh start %s" % configs[1],)
    shutdown = ("bash haproxy.sh stop",)
    validate = ("pidof haproxy",)
    
    @classmethod
    def on_load(cls):
        """
        Provides a way to run some arbitrary logic when the service is loaded, possibly to help facilitate
        dynamic settings for the environment.

        :return: nothing
        """
        pass

    @classmethod
    def get_configs(cls, node):
        """
        Provides a way to dynamically generate the config files from the node a service will run.
        Defaults to the class definition and can be left out entirely if not needed.

        :param node: core node that the service is being ran on
        :return: tuple of config files to create
        """
        return cls.configs

    @classmethod
    def generate_config(cls, node, filename):
        #
        # Generate haproxy script start/stop and config files.
        #
        if filename == cls.configs[0]:
            cfg = "#!/bin/bash\n"
            cfg += "# haproxy.sh generated by haproxy.py\n\n"
            cfg += """\
HAPROXY_PATH="/usr/local/bin/haproxy"

if [ "$1" == "start" ]
then
	echo "Starting..."
	$HAPROXY_PATH -V -D -f $2
elif [ "$1" == "stop" ]
then
	echo "Stopping..."
	kill `pidof haproxy`
else
	echo "Invalid parameter! Exiting..."
fi
"""
            return cfg
        elif filename == cls.configs[1]:
            cfg = "# haproxy.conf generated by haproxy.py\n"
            cfg += """\
global
    debug	# uncomment to enable debug mode for HAProxy

defaults
    #log /dev/log local0	# enable log on syslog (doesn't work under chroot)
    log localhost:514 local0	# enable log on syslog (to work under chroot)
    mode http		# enable http mode which gives of layer 7 filtering
    timeout connect 5000ms	# max time to wait for a connection attempt to a server to succeed
    timeout client 50000ms	# max inactivity time on the client side
    timeout server 50000ms	# max inactivity time on the server side

frontend http
    bind localhost:80
    bind 10.0.0.1:80
    default_backend apache_80

backend apache_80
    server node01 10.0.1.10:80 check fall 3 rise 2
    server node02 10.0.1.11:80 check fall 3 rise 2
    server node03 10.0.1.12:80 check fall 3 rise 2
"""
            return cfg
        else:
            return ""

    @classmethod
    def get_startup(cls, node):
        """
        Provides a way to dynamically generate the startup commands from the node a service will run.
        Defaults to the class definition and can be left out entirely if not needed.

        :param node: core node that the service is being ran on
        :return: tuple of startup commands to run
        """
        return cls.startup

    @classmethod
    def get_validate(cls, node):
        """
        Provides a way to dynamically generate the validate commands from the node a service will run.
        Defaults to the class definition and can be left out entirely if not needed.

        :param node: core node that the service is being ran on
        :return: tuple of commands to validate service startup with
        """
        return cls.validate
