# 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"
                        # TODO: get timeline too?
                        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()
