# author: Alex Savatieiev (osavatieiev@mirantis.com)
from gevent import monkey, pywsgi
monkey.patch_all()
import falcon # noqa E402
import os # noqa E402
import json # noqa E402

from copy import deepcopy # noqa E402
from platform import system, release, node # noqa E402

from cfg_checker.common.log import logger # noqa E402
from cfg_checker.common.settings import pkg_dir  # noqa E402
from cfg_checker.common.exception import CheckerException  # noqa E402
from cfg_checker.helpers.falcon_jinja2 import FalconTemplate  # noqa E402
from .fio_runner import FioProcessShellRun, get_time # noqa E402

template = FalconTemplate(
    path=os.path.join(pkg_dir, "templates")
)

_module_status = {
    "status": "unknown",
    "healthcheck": {},
    "actions": [],
    "options": {},
    "uri": "<agent_uri>/api/<modile_name>",
}

_action = {
    "module": "<name>",
    "action": "<action>",
    "options": "<options_dict>"
}

_modules = {
    "fio": deepcopy(_module_status)
}

_status = {
    "agent": {
        "started": get_time()
    },
    "modules": list(_modules.keys()),
    "help": {
        ".../api": {
            "GET": "<this_status>",
            "POST": json.dumps(_action)
        },
        ".../api/<module_name>": {
            "GET": "returns healthcheck and module help"
        }
    }
}

# Populate modules
_fio = FioProcessShellRun()


def _init_status(mod):
    _modules[mod]["uri"] = "<agent_uri>/api/fio"
    _modules[mod]["actions"] = list(_fio.actions.keys())


def _update_status(mod):
    _modules[mod]["healthcheck"] = _fio.hchk
    _modules[mod]["options"] = _fio.get_options()
    _modules[mod].update(_fio.status())


class FioStatus:
    _name = "fio"

    def on_get(self, req, resp):
        # Hacky way to handle empty request
        _m = req.get_media(default_when_empty={})
        if "fast" in _m and _m["fast"]:
            resp.status = falcon.HTTP_200
            resp.content_type = "application/json"
            resp.text = json.dumps(_fio.status())
        else:
            _update_status(self._name)

            resp.status = falcon.HTTP_200
            resp.content_type = "application/json"
            resp.text = json.dumps(_modules[self._name])


class Api:
    def on_get(self, req, resp):
        # return api status
        resp.status = falcon.HTTP_200
        resp.content_type = "application/json"
        resp.text = json.dumps(_status)

    def on_post(self, req, resp):
        def _resp(resp, code, msg, opt={}):
            resp.status = code
            resp.content_type = "application/json"
            resp.text = json.dumps({"error": msg, "options": opt})
        # Handle actions
        logger.info("Getting media")
        try:
            _m = req.stream.read()
            _m = json.loads(_m)
        except json.JSONDecodeError:
            _msg = "Incorrect input data"
            logger.error(_msg)
            _resp(resp, falcon.HTTP_400, _msg)
            return
        if _m:
            logger.debug("got media object:\n{}".format(json.dumps(_m)))
            # Validate action structure
            _module = _m.get('module', "")
            _action = _m.get('action', "")
            _options = _m.get('options', {})

            if not _module or _module not in list(_modules.keys()):
                logger.error("invalid module '{}'".format(_module))
                _resp(
                    resp,
                    falcon.HTTP_400,
                    "Invalid module '{}'".format(_module)
                )
                return
            elif not _action or _action not in _modules[_module]['actions']:
                logger.error("invalid action '{}'".format(_action))
                _resp(
                    resp,
                    falcon.HTTP_400,
                    "Invalid action '{}'".format(_action)
                )
                return
            else:
                # Handle command
                _a = _fio.actions[_action]
                try:
                    if _action == 'get_options':
                        logger.info("returning options")
                        resp.status = falcon.HTTP_200
                        resp.content_type = "application/json"
                        resp.text = json.dumps({"options": _a()})
                    elif _action == 'get_resultlist':
                        logger.info("getting results")
                        resp.status = falcon.HTTP_200
                        resp.content_type = "application/json"
                        resp.text = json.dumps({"resultlist": _a()})
                    elif _action == 'get_result':
                        if 'time' not in _options:
                            _msg = "No 'time' found for '{}'".format(_action)
                            logger.error(_msg)
                            _resp(
                                resp,
                                falcon.HTTP_400,
                                _msg
                            )
                            return
                        _time = _options['time']
                        logger.info("getting results for '{}'".format(_time))
                        resp.status = falcon.HTTP_200
                        resp.content_type = "application/json"
                        resp.text = json.dumps({_time: _a(_time)})
                    elif _action == 'do_singlerun':
                        logger.info("executing single run")
                        _a(_options)
                        resp.status = falcon.HTTP_200
                        resp.content_type = "application/json"
                        resp.text = json.dumps({"ok": True})
                    elif _action == 'do_scheduledrun':
                        logger.info("executing scheduled run")
                        # prepare scheduled run

                        # Run it
                        _a(_options)
                        resp.status = falcon.HTTP_200
                        resp.content_type = "application/json"
                        resp.text = json.dumps({"ok": True})
                    else:
                        _msg = "Unknown error happened for '{}/{}/{}'".format(
                                _module,
                                _action,
                                _options
                            )
                        logger.error(_msg)
                        _resp(resp, falcon.HTTP_500, _msg)
                except CheckerException as e:
                    _msg = "Error for '{}/{}':\n{}".format(
                                _module,
                                _action,
                                e
                            )
                    logger.error(_msg)
                    _resp(resp, falcon.HTTP_500, _msg, opt=_options)
                return
        else:
            _msg = "Empty request body"
            logger.error(_msg)
            _resp(resp, falcon.HTTP_400, _msg)


class Index:
    @template.render("agent_index_html.j2")
    def on_get(self, request, response):
        # prepare template context
        _context = {
            "gen_date": get_time(),
            "system": system(),
            "release": release(),
            "hostname": node()
        }
        _context.update(_status)
        # creating response
        response.status = falcon.HTTP_200
        response.content_type = "text/html"
        response.context = _context


def agent_server(host="0.0.0.0", port=8765):
    # init api
    api = falcon.API()
    # populate pages
    api.add_route("/", Index())
    api.add_route("/api/", Api())

    # Populate modules list
    _active_modules = [FioStatus]
    # init modules
    for mod in _active_modules:
        _init_status(mod._name)
        _update_status(mod._name)

        api.add_route("/api/"+mod._name, mod())

    # init and start server
    server = pywsgi.WSGIServer((host, port), api)
    server.serve_forever()
