# -*- coding: utf-8 -*-

##
# Copyright 2020 Telefonica S.A.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
##

import asyncio
from time import time
import logging
import aiohttp
import yaml
import os
from osm_lcm.lcm_utils import LcmException
from osm_common.dbbase import DbException
from osm_lcm.data_utils.database.database import Database
from jinja2 import Template, TemplateError, TemplateNotFound, TemplateSyntaxError

__author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"

initial_prometheus_data = {
    "_id": "prometheus",
    "_admin": {
        "locked_at": 0,
        "locked_by": None,
        "modified": 1593445184,  # 2020-06-29
        "created": 1593445184,
        "version": "1.0"    # to allow future version updates
    },
    'scrape_configs': {   # Dictionary at database. Converted to list before sending to prometheus
        'mon_exporter': {'static_configs': [{'targets': ['mon:8000']}], 'job_name': 'mon_exporter'},
    },
    'global': {'evaluation_interval': '15s', 'scrape_interval': '15s'},
    'rule_files': None,
    'alerting': {'alertmanagers': [{'static_configs': [{'targets': None}]}]}
}


class Prometheus:
    """
    Implements a class to update Prometheus
    """

    PROMETHEUS_LOCKED_TIME = 120

    def __init__(self, config, worker_id, loop, logger=None):
        self.worker_id = worker_id
        self.db = Database().instance.db
        self.loop = loop
        self.logger = logger or logging.getLogger("lcm.prometheus")
        self.server = config["uri"]
        self.path = config["path"]
        if not self.path.endswith("/"):
            self.path += "/"
        self.cfg_file = self.path + "prometheus.yml"
        self.cfg_file_backup = self.path + "prometheus.yml-backup"

    @staticmethod
    def parse_job(job_data: str, variables: dict) -> dict:
        try:
            template = Template(job_data)
            job_parsed = template.render(variables or {})
            return yaml.safe_load(job_parsed)
        except (TemplateError, TemplateNotFound, TemplateSyntaxError) as e:
            # TODO yaml exceptions
            raise LcmException("Error parsing Jinja2 to prometheus job. job_data={}, variables={}. Error={}".format(
                job_data, variables, e))

    async def start(self):
        for retry in range(4):
            try:
                # self.logger("Starting prometheus ")
                # read from database
                prometheus_data = self.db.get_one("admin", {"_id": "prometheus"}, fail_on_empty=False)
                if not prometheus_data:
                    self.logger.info("Init db.admin.prometheus content")
                    self.db.create("admin", initial_prometheus_data)
                # send database config file to prometheus. Ignore loading errors, as prometheus may be starting
                # but at least an initial configuration file is set
                await self.update()
                return
            except DbException as e:
                if retry == 3:
                    raise LcmException("Max retries trying to init prometheus configuration: {}".format(e))
                await asyncio.sleep(5, loop=self.loop)

    async def update(self, add_jobs: dict = None, remove_jobs: list = None) -> bool:
        """

        :param add_jobs: dictionary with {job_id_1: job_content, job_id_2: job_content}
        :param remove_jobs: list with jobs to remove [job_id_1, job_id_2]
        :return: result. If false prometheus denies this configuration. Exception on error
        """
        for retry in range(20):
            result = True
            if retry:  # first time do not wait
                await asyncio.sleep(4 + retry, loop=self.loop)

            # lock database
            now = time()
            if not self.db.set_one(
                    "admin",
                    q_filter={"_id": "prometheus", "_admin.locked_at.lt": now - self.PROMETHEUS_LOCKED_TIME},
                    update_dict={"_admin.locked_at": now, "_admin.locked_by": self.worker_id},
                    fail_on_empty=False):
                continue
            # read database
            prometheus_data = self.db.get_one("admin", {"_id": "prometheus"})
            update_dict = {"_admin.locked_at": 0,
                           "_admin.locked_by": None}

            # Make changes from prometheus_incremental
            push_dict = pull_dict = None
            if add_jobs or remove_jobs:
                log_text_list = []
                if add_jobs:
                    log_text_list.append("adding jobs: {}".format(list(add_jobs.keys())))
                    prometheus_data["scrape_configs"].update(add_jobs)
                    push_dict = {"scrape_configs." + job_id: job_data for job_id, job_data in add_jobs.items()}
                elif remove_jobs:
                    log_text_list.append("removing jobs: {}".format(list(remove_jobs)))
                    for job_id in remove_jobs:
                        prometheus_data["scrape_configs"].pop(job_id, None)
                    pull_dict = {"scrape_configs." + job_id: None for job_id in remove_jobs}
                self.logger.debug("Updating. " + ". ".join(log_text_list))

            if not await self.send_data(prometheus_data):
                self.logger.error("Cannot update add_jobs: {}. remove_jobs: {}".format(add_jobs, remove_jobs))
                push_dict = pull_dict = None
                result = False

            # unblock database
            if push_dict:
                update_dict.update(push_dict)
            if push_dict or pull_dict:
                update_dict["_admin.modified_at"] = now
            if not self.db.set_one(
                    "admin", {"_id": "prometheus", "_admin.locked_at": now, "_admin.locked_by": self.worker_id},
                    update_dict=update_dict, unset=pull_dict, fail_on_empty=False):
                continue
            return result
        raise LcmException("Cannot update prometheus database. Reached max retries")

    async def send_data(self, new_config):
        restore_backup = False
        del new_config["_id"]
        del new_config["_admin"]
        new_scrape_configs = []

        # generate a list with the values of scrape_configs
        for scrape_config in new_config["scrape_configs"].values():
            scrape_config = scrape_config.copy()
            # remove nsr_id metadata from scrape_configs
            scrape_config.pop("nsr_id", None)
            new_scrape_configs.append(scrape_config)
        new_config["scrape_configs"] = new_scrape_configs

        try:
            if os.path.exists(self.cfg_file):
                os.rename(self.cfg_file, self.cfg_file_backup)
                restore_backup = True
            with open(self.cfg_file, "w+") as f:
                yaml.safe_dump(new_config, f, indent=4, default_flow_style=False)
            # self.logger.debug("new configuration: {}".format(yaml.safe_dump(new_config, indent=4,
            #                                                                 default_flow_style=False)))
            async with aiohttp.ClientSession() as session:
                async with session.post(self.server + "-/reload") as resp:
                    if resp.status > 204:
                        raise LcmException(await resp.text())
                await asyncio.sleep(5, loop=self.loop)
                # If prometheus does not admit this configuration, remains with the old one
                # Then, to check if the configuration has been accepted, get the configuration from prometheus
                # and compares with the inserted one
                async with session.get(self.server + "api/v1/status/config") as resp:
                    if resp.status > 204:
                        raise LcmException(await resp.text())
                    current_config = await resp.json()
                    if not self._check_configuration_equal(current_config, new_config):
                        return False
                    else:
                        restore_backup = False
            return True
        except Exception as e:
            self.logger.error("Error updating configuration url={}: {}".format(self.server, e))
            return False
        finally:
            if restore_backup:
                try:
                    os.rename(self.cfg_file_backup, self.cfg_file)
                except Exception as e:
                    self.logger.critical("Exception while rolling back: {}".format(e))

    def _check_configuration_equal(self, current_config, expected_config):
        try:
            # self.logger.debug("Comparing current_config='{}' with expected_config='{}'".format(current_config,
            #                                                                                    expected_config))
            current_config_yaml = yaml.safe_load(current_config['data']['yaml'])
            current_jobs = [j["job_name"] for j in current_config_yaml["scrape_configs"]]
            expected_jobs = [j["job_name"] for j in expected_config["scrape_configs"]]
            if current_jobs == expected_jobs:
                return True
            else:
                self.logger.error("Not all jobs have been loaded. Target jobs: {} Loaded jobs: {}".format(
                    expected_jobs, current_jobs))
                return False
        except Exception as e:
            self.logger.error("Invalid obtained status from server. Error: '{}'. Obtained data: '{}'".format(
                e, current_config))
            # if format is not understood, cannot be compared, assume it is ok
            return True
