# -*- 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)
            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!')
