#!/usr/bin/env python3
#
# Copyright (c) 2016 Roberto Riggio
#
# 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.

"""EmPOWER base app class."""

import tornado.ioloop
import empower.logger

from empower.main import RUNTIME

DEFAULT_PERIOD = 5000


class EmpowerApp(object):
    """EmpowerApp base app class."""

    def __init__(self, tenant_id, **kwargs):

        self.__tenant_id = tenant_id
        self.__every = DEFAULT_PERIOD
        self.app_name = self.__module__.split(".")[-1]
        self.params = []
        self.log = empower.logger.get_logger()
        self.worker = tornado.ioloop.PeriodicCallback(self.loop, self.every)

        for param in kwargs:
            if hasattr(self, param):
                setattr(self, param, kwargs[param])
                self.params.append(param)

    @property
    def tenant_id(self):
        """Return tenant_id."""

        return self.__tenant_id

    @property
    def tenant(self):
        """Return tenant instance."""

        return RUNTIME.tenants[self.tenant_id]

    @property
    def every(self):
        """Return loop period."""

        return self.__every

    @every.setter
    def every(self, value):
        """Set loop period."""

        self.log.info("Setting control loop interval to %u", value)
        self.__every = int(value)

    def start(self):
        """Start control loop."""

        self.worker.start()

    def stop(self):
        """Stop control loop."""

        self.worker.stop()

    def to_dict(self):
        """Return JSON-serializable representation of the object."""

        params = {}

        params['app_name'] = self.app_name
        params['tenant_id'] = self.tenant_id
        params['ui_url'] = "/apps/tenants/%s/%s/" % \
            (self.tenant_id, self.app_name)
        params['params'] = self.params

        for param in self.params:
            params[param] = getattr(self, param)

        return params

    def loop(self):
        """Control loop."""

        pass

    def wtps(self):
        """Return WTPs in this tenant."""

        if self.tenant_id not in RUNTIME.tenants:
            return None

        return RUNTIME.tenants[self.tenant_id].wtps.values()

    def lvaps(self):
        """Return LVAPs in this tenant."""

        if self.tenant_id not in RUNTIME.tenants:
            return None

        return RUNTIME.tenants[self.tenant_id].lvaps.values()

    def lvap(self, addr):
        """Return a particular LVAP in this tenant."""

        if self.tenant_id not in RUNTIME.tenants:
            return None

        if addr not in RUNTIME.tenants[self.tenant_id].lvaps:
            return None

        return RUNTIME.tenants[self.tenant_id].lvaps[addr]

    def wtp(self, addr):
        """Return a particular WTP in this tenant."""

        if self.tenant_id not in RUNTIME.tenants:
            return None

        if addr not in RUNTIME.tenants[self.tenant_id].wtps:
            return None

        return RUNTIME.tenants[self.tenant_id].wtps[addr]

    def cpps(self):
        """Return CPPs in this tenant."""

        if self.tenant_id not in RUNTIME.tenants:
            return None

        return RUNTIME.tenants[self.tenant_id].cpps.values()

    def cpp(self, addr):
        """Return a particular CPP in this tenant."""

        if self.tenant_id not in RUNTIME.tenants:
            return None

        if addr not in RUNTIME.tenants[self.tenant_id].cpps:
            return None

        return RUNTIME.tenants[self.tenant_id].cpps[addr]

    def lvnfs(self):
        """Return LVNFs in this tenant."""

        if self.tenant_id not in RUNTIME.tenants:
            return None

        return RUNTIME.tenants[self.tenant_id].lvnfs.values()

    def lvnf(self, addr):
        """Return a particular LVNF in this tenant."""

        if self.tenant_id not in RUNTIME.tenants:
            return None

        if addr not in RUNTIME.tenants[self.tenant_id].lvnfs:
            return None

        return RUNTIME.tenants[self.tenant_id].lvnfs[addr]

@@ -2480,18 +2480,19 @@
     def 
-wt
+vbs
 ps(self)
@@ -2511,18 +2511,19 @@
 %22Return 
-WT
+VBS
 Ps in th
@@ -2659,18 +2659,19 @@
 ant_id%5D.
-wt
+vbs
 ps.value
@@ -2667,32 +2667,336 @@
 vbsps.values()%0A%0A
+    def vbsp(self, addr):%0A        %22%22%22Return a particular VBSP in this tenant.%22%22%22%0A%0A        if self.tenant_id not in RUNTIME.tenants:%0A            return None%0A%0A        if addr not in RUNTIME.tenants%5Bself.tenant_id%5D.vbsps:%0A            return None%0A%0A        return RUNTIME.tenants%5Bself.tenant_id%5D.vbsps%5Baddr%5D%0A%0A
     def lvaps(se
@@ -3418,32 +3418,32 @@
    return None%0A%0A
-
         return R
@@ -3478,32 +3478,232 @@
 d%5D.lvaps%5Baddr%5D%0A%0A
+    def wtps(self):%0A        %22%22%22Return WTPs in this tenant.%22%22%22%0A%0A        if self.tenant_id not in RUNTIME.tenants:%0A            return None%0A%0A        return RUNTIME.tenants%5Bself.tenant_id%5D.wtps.values()%0A%0A
     def wtp(self

add vbsp handlers