##
# Copyright 2019 Telefonica Investigacion y Desarrollo, S.A.U.
# This file is part of OSM
# All Rights Reserved.
#
# 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 with: nfvlabs@tid.es
##

import asyncio
import time

from juju.model import ModelObserver, Model
from juju.machine import Machine
from juju.application import Application
from juju.action import Action

from n2vc.n2vc_conn import N2VCConnector, juju_status_2_osm_status
from n2vc.exceptions import N2VCTimeoutException


class _Entity:
    def __init__(self, entity_id: str, entity_type: str, obj: object, db_dict: dict):
        self.entity_id = entity_id
        self.entity_type = entity_type
        self.obj = obj
        self.event = asyncio.Event()
        self.db_dict = db_dict


class JujuModelObserver(ModelObserver):

    def __init__(self, n2vc: N2VCConnector, model: Model):
        self.n2vc = n2vc
        self.model = model
        model.add_observer(self)
        self.machines = dict()
        self.applications = dict()
        self.actions = dict()

    def register_machine(self, machine: Machine, db_dict: dict):
        try:
            entity_id = machine.entity_id
        except Exception as e:
            # no entity_id aatribute, try machine attribute
            entity_id = machine.machine
        # self.n2vc.debug(msg='Registering machine for change notifications: {}'.format(entity_id))
        entity = _Entity(entity_id=entity_id, entity_type='machine', obj=machine, db_dict=db_dict)
        self.machines[entity_id] = entity

    def unregister_machine(self, machine_id: str):
        if machine_id in self.machines:
            del self.machines[machine_id]

    def is_machine_registered(self, machine_id: str):
        return machine_id in self.machines

    def register_application(self, application: Application, db_dict: dict):
        entity_id = application.entity_id
        # self.n2vc.debug(msg='Registering application for change notifications: {}'.format(entity_id))
        entity = _Entity(entity_id=entity_id, entity_type='application', obj=application, db_dict=db_dict)
        self.applications[entity_id] = entity

    def unregister_application(self, application_id: str):
        if application_id in self.applications:
            del self.applications[application_id]

    def is_application_registered(self, application_id: str):
        return application_id in self.applications

    def register_action(self, action: Action, db_dict: dict):
        entity_id = action.entity_id
        # self.n2vc.debug(msg='Registering action for changes notifications: {}'.format(entity_id))
        entity = _Entity(entity_id=entity_id, entity_type='action', obj=action, db_dict=db_dict)
        self.actions[entity_id] = entity

    def unregister_action(self, action_id: str):
        if action_id in self.actions:
            del self.actions[action_id]

    def is_action_registered(self, action_id: str):
        return action_id in self.actions

    async def wait_for_machine(
            self,
            machine_id: str,
            progress_timeout: float = None,
            total_timeout: float = None) -> int:

        if not self.is_machine_registered(machine_id):
            return

        self.n2vc.debug('Waiting for machine completed: {}'.format(machine_id))

        # wait for a final state
        entity = self.machines[machine_id]
        return await self._wait_for_entity(
            entity=entity,
            field_to_check='agent_status',
            final_states_list=['started'],
            progress_timeout=progress_timeout,
            total_timeout=total_timeout)

    async def wait_for_application(
            self,
            application_id: str,
            progress_timeout: float = None,
            total_timeout: float = None) -> int:

        if not self.is_application_registered(application_id):
            return

        self.n2vc.debug('Waiting for application completed: {}'.format(application_id))

        # application statuses: unknown, active, waiting
        # wait for a final state
        entity = self.applications[application_id]
        return await self._wait_for_entity(
            entity=entity,
            field_to_check='status',
            final_states_list=['active', 'blocked'],
            progress_timeout=progress_timeout,
            total_timeout=total_timeout)

    async def wait_for_action(
            self,
            action_id: str,
            progress_timeout: float = None,
            total_timeout: float = None) -> int:

        if not self.is_action_registered(action_id):
            return

        self.n2vc.debug('Waiting for action completed: {}'.format(action_id))

        # action statuses: pending, running, completed, failed, cancelled
        # wait for a final state
        entity = self.actions[action_id]
        return await self._wait_for_entity(
            entity=entity,
            field_to_check='status',
            final_states_list=['completed', 'failed', 'cancelled'],
            progress_timeout=progress_timeout,
            total_timeout=total_timeout)

    async def _wait_for_entity(
            self,
            entity: _Entity,
            field_to_check: str,
            final_states_list: list,
            progress_timeout: float = None,
            total_timeout: float = None) -> int:

        # default values for no timeout
        if total_timeout is None:
            total_timeout = 100000
        if progress_timeout is None:
            progress_timeout = 100000

        # max end time
        now = time.time()
        total_end = now + total_timeout

        if now >= total_end:
            raise N2VCTimeoutException(
                message='Total timeout {} seconds, {}: {}'.format(total_timeout, entity.entity_type, entity.entity_id),
                timeout='total'
            )

        # update next progress timeout
        progress_end = now + progress_timeout  # type: float

        # which is closest? progress or end timeout?
        closest_end = min(total_end, progress_end)

        next_timeout = closest_end - now

        retries = 0

        while entity.obj.__getattribute__(field_to_check) not in final_states_list:
            retries += 1
            if await _wait_for_event_or_timeout(entity.event, next_timeout):
                entity.event.clear()
            else:
                message = 'Progress timeout {} seconds, {}}: {}'\
                    .format(progress_timeout, entity.entity_type, entity.entity_id)
                self.n2vc.debug(message)
                raise N2VCTimeoutException(message=message, timeout='progress')
        # self.n2vc.debug('End of wait. Final state: {}, retries: {}'
        #                 .format(entity.obj.__getattribute__(field_to_check), retries))
        return retries

    async def on_change(self, delta, old, new, model):

        if new is None:
            return

        # log
        # self.n2vc.debug('on_change(): type: {}, entity: {}, id: {}'
        #                 .format(delta.type, delta.entity, new.entity_id))

        if delta.entity == 'machine':

            # check registered machine
            if new.entity_id not in self.machines:
                return

            # write change in database
            await self.n2vc.write_app_status_to_db(
                db_dict=self.machines[new.entity_id].db_dict,
                status=juju_status_2_osm_status(delta.entity, new.agent_status),
                detailed_status=new.status_message,
                vca_status=new.status,
                entity_type='machine'
            )

            # set event for this machine
            self.machines[new.entity_id].event.set()

        elif delta.entity == 'application':

            # check registered application
            if new.entity_id not in self.applications:
                return

            # write change in database
            await self.n2vc.write_app_status_to_db(
                db_dict=self.applications[new.entity_id].db_dict,
                status=juju_status_2_osm_status(delta.entity, new.status),
                detailed_status=new.status_message,
                vca_status=new.status,
                entity_type='application'
            )

            # set event for this application
            self.applications[new.entity_id].event.set()

        elif delta.entity == 'unit':

            # get the application for this unit
            application_id = delta.data['application']

            # check registered application
            if application_id not in self.applications:
                return

            # write change in database
            if not new.dead:
                await self.n2vc.write_app_status_to_db(
                    db_dict=self.applications[application_id].db_dict,
                    status=juju_status_2_osm_status(delta.entity, new.workload_status),
                    detailed_status=new.workload_status_message,
                    vca_status=new.workload_status,
                    entity_type='unit'
                )

            # set event for this application
            self.applications[application_id].event.set()

        elif delta.entity == 'action':

            # check registered action
            if new.entity_id not in self.actions:
                return

            # write change in database
            await self.n2vc.write_app_status_to_db(
                db_dict=self.actions[new.entity_id].db_dict,
                status=juju_status_2_osm_status(delta.entity, new.status),
                detailed_status=new.status,
                vca_status=new.status,
                entity_type='action'
            )

            # set event for this application
            self.actions[new.entity_id].event.set()


async def _wait_for_event_or_timeout(event: asyncio.Event, timeout: float = None):
    try:
        await asyncio.wait_for(fut=event.wait(), timeout=timeout)
    except asyncio.TimeoutError:
        pass
    return event.is_set()
