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

# Copyright 2018 Whitestack, LLC
# *************************************************************

# This file is part of OSM Monitoring module
# All Rights Reserved to Whitestack, LLC

# 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.
# For those usages not covered by the Apache License, Version 2.0 please
# contact: bdiaz@whitestack.com or glavado@whitestack.com
##
import logging
import time
import socket
import asyncio

from osm_mon.dashboarder.service import DashboarderService
from osm_mon.core.config import Config
from osm_mon.core.message_bus_client import MessageBusClient

log = logging.getLogger(__name__)


class Dashboarder:
    def __init__(self, config: Config, loop=None):
        self.conf = config
        self.service = DashboarderService(config)
        if not loop:
            loop = asyncio.get_event_loop()
        self.loop = loop
        self.msg_bus = MessageBusClient(config)

    # run consumer for grafana user management
    def run(self):
        self.loop.run_until_complete(self.start())

    async def start(self):
        topics = ["users", "project"]
        await self.msg_bus.aioread(topics, self._user_msg)

    async def _user_msg(self, topic, key, values):
        log.debug("Message from kafka bus received: topic: %s and values: %s and key: %s", topic, values, key)
        try:
            if topic == "users" and key == "created":
                log.debug("Received message from kafka for creating user")
                user = values['username']
                self.service.create_grafana_user(user)
            elif topic == "users" and key == "deleted":
                log.debug("Received message from kafka for deleting user")
                user = values['username']
                self.service.delete_grafana_user(user)
                log.info("Grafana user deleted: %s", user)
            elif topic == "users" and key == "edited":
                log.debug("Received message from kafka for associating user to team")
                user_id = values["_id"]
                project_data = values["changes"]["project_role_mappings"]
                self.service.create_grafana_team_member(project_data, user_id)
            elif topic == "project" and key == "created":
                log.debug("Received message from kafka for creating team")
                team_name = values["name"]
                self.service.create_grafana_team(team_name)
            elif topic == "project" and key == "deleted":
                log.debug("Received message from kafka for deleting team")
                project_name = values["name"]
                self.service.delete_grafana_team(project_name)
            elif topic == "project" and key == "edited":
                log.debug("Received message from kafka for team name update")
                project_old_name = values["original"]["name"]
                project_new_name = values["changes"]["name"]
                self.service.update_grafana_team(project_new_name, project_old_name)
        except Exception:
            log.exception("Exception processing message: ")

    def dashboard_forever(self):
        log.debug('dashboard_forever')
        while True:
            try:
                socket.gethostbyname("grafana")
                log.debug("Dashboard backend is running")
            except socket.error:
                log.debug("Dashboard backend is not available")
                time.sleep(int(self.conf.get('dashboarder', 'interval')))
                continue
            try:
                self.create_dashboards()
                time.sleep(int(self.conf.get('dashboarder', 'interval')))
            except Exception:
                log.exception("Error creating dashboards")

    def create_dashboards(self):
        self.service.create_dashboards()
        log.debug('I just called the dashboarder service!')
