# Copyright 2017-present Open Networking Foundation
#
# 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 json
import requests
from requests.auth import HTTPBasicAuth
from xossynchronizer.steps.syncstep import SyncStep, DeferredException
from xossynchronizer.modelaccessor import model_accessor
from xossynchronizer.modelaccessor import ONOSApp, ServiceInstance, ServiceInstanceAttribute

from xosconfig import Config
from multistructlog import create_logger

from helpers import Helpers

log = create_logger(Config().get('logging'))
log.info("config file", file=Config().get_config_file())


class SyncONOSApp(SyncStep):
    provides = [ONOSApp]
    observes = [ONOSApp, ServiceInstanceAttribute]

    def get_service_instance_attribute(self, o):
        # NOTE this method is defined in the core convenience methods for service_instances
        svc = ServiceInstance.objects.get(id=o.id)
        return svc.serviceinstanceattribute_dict

    def check_app_dependencies(self, deps):
        """
        Check if all the dependencies required by this application are installed
        :param deps: comma separated list of application names
        :return: bool
        """
        if not deps:
            return True
        for dep in [x.strip() for x in deps.split(',') if x != ""]:
            try:
                app = ONOSApp.objects.get(app_id=dep)
                if not app.backend_code == 1:
                    # backend_code == 1 means that the app has been pushed
                    return False
            except IndexError:
                return False
        return True

    def add_config(self, o):
        log.info("Adding config %s" % o.name, model=o.tologdict())
        # getting onos url and auth
        onos_url = "%s:%s" % (Helpers.format_url(
            o.service_instance.leaf_model.owner.leaf_model.rest_hostname),
            o.service_instance.leaf_model.owner.leaf_model.rest_port)
        onos_basic_auth = HTTPBasicAuth(
            o.service_instance.leaf_model.owner.leaf_model.rest_username,
            o.service_instance.leaf_model.owner.leaf_model.rest_password)

        # push configs (if any)
        url = o.name
        if url[0] == "/":
            # strip initial /
            url = url[1:]

        url = '%s/%s' % (onos_url, url)
        value = json.loads(o.value)
        request = requests.post(url, json=value, auth=onos_basic_auth)

        if request.status_code != 200:
            log.error("Request failed", response=request.text)
            raise Exception("Failed to add config %s in ONOS:  %s" % (url, request.text))

    def activate_app(self, o, onos_url, onos_basic_auth):
        log.info("Activating app %s" % o.app_id)
        url = '%s/onos/v1/applications/%s/active' % (onos_url, o.app_id)
        request = requests.post(url, auth=onos_basic_auth)

        if request.status_code != 200:
            log.error("Request failed", response=request.text)
            raise Exception("Failed to add application %s to ONOS: %s" % (url, request.text))

        url = '%s/onos/v1/applications/%s' % (onos_url, o.app_id)
        request = requests.get(url, auth=onos_basic_auth)

        if request.status_code != 200:
            log.error("Request failed", response=request.text)
            raise Exception("Failed to read application %s from ONOS: %s" % (url, request.text))
        else:
            o.version = request.json()["version"]

    def check_app_installed(self, o, onos_url, onos_basic_auth):
        log.debug("Checking if app is installed", app=o.app_id)
        url = '%s/onos/v1/applications/%s' % (onos_url, o.app_id)
        request = requests.get(url, auth=onos_basic_auth)

        if request.status_code == 200:
            if "version" in request.json() and o.version == request.json()["version"]:
                log.debug("App is installed", app=o.app_id)
                return True
            else:
                # uninstall the application
                self.uninstall_app(o, onos_url, onos_basic_auth)
                return False
        if request.status_code == 404:
            # app is not installed at all
            return False
        else:
            log.error("Request failed", response=request.text)
            raise Exception("Failed to read application %s from ONOS aaa: %s" % (url, request.text))

    def install_app(self, o, onos_url, onos_basic_auth):
        log.info("Installing app from url %s" % o.url, app=o.app_id, version=o.version)

        # check is the already installed app is the correct version
        is_installed = self.check_app_installed(o, onos_url, onos_basic_auth)

        if is_installed:
            # if the app is already installed we don't need to do anything
            log.info("App is installed, skipping install", app=o.app_id)
            return

        data = {
            'activate': True,
            'url': o.url
        }
        url = '%s/onos/v1/applications' % onos_url
        request = requests.post(url, json=data, auth=onos_basic_auth)

        if request.status_code == 409:
            log.info("App was already installed", app=o.app_id, test=request.text)
            return

        if request.status_code != 200:
            log.error("Request failed", response=request.text)
            raise Exception("Failed to add application %s to ONOS: %s" % (url, request.text))

        log.debug("App from url %s installed" % o.url, app=o.app_id, version=o.version)

        url = '%s/onos/v1/applications/%s' % (onos_url, o.app_id)
        request = requests.get(url, auth=onos_basic_auth)

        if request.status_code != 200:
            log.error("Request failed", response=request.text)
            raise Exception(
                "Failed to read application %s from ONOS: %s while checking correct version" %
                (url, request.text))
        else:
            if o.version != request.json()["version"]:
                raise Exception(
                    "The version of %s you installed (%s) is not the same you requested (%s)" %
                    (o.app_id, request.json()["version"], o.version))

    def sync_record(self, o):
        log.info("Sync'ing", model=o.tologdict())
        if hasattr(o, 'service_instance'):
            # this is a ServiceInstanceAttribute model just push the config
            if 'ONOSApp' in o.service_instance.leaf_model.class_names:
                return self.add_config(o)
            return  # if it's not an ONOSApp do nothing

        if not self.check_app_dependencies(o.dependencies):
            raise DeferredException('Deferring installation of ONOSApp with id %s as dependencies are not met' % o.id)

        # getting onos url and auth
        onos_url = "%s:%s" % (Helpers.format_url(o.owner.leaf_model.rest_hostname), o.owner.leaf_model.rest_port)
        onos_basic_auth = HTTPBasicAuth(o.owner.leaf_model.rest_username, o.owner.leaf_model.rest_password)

        # activate app (bundled in onos)
        if not o.url or o.url is None:
            self.activate_app(o, onos_url, onos_basic_auth)
        # install an app from a remote source
        if o.url and o.url is not None:
            self.install_app(o, onos_url, onos_basic_auth)

    def delete_config(self, o):
        log.info("Deleting config %s" % o.name)
        # getting onos url and auth
        onos_app = o.service_instance.leaf_model
        onos_url = "%s:%s" % (Helpers.format_url(
            onos_app.owner.leaf_model.rest_hostname),
            onos_app.owner.leaf_model.rest_port)
        onos_basic_auth = HTTPBasicAuth(
            onos_app.owner.leaf_model.rest_username,
            onos_app.owner.leaf_model.rest_password)

        url = o.name
        if url[0] == "/":
            # strip initial /
            url = url[1:]

        url = '%s/%s' % (onos_url, url)
        request = requests.delete(url, auth=onos_basic_auth)

        if request.status_code != 204:
            log.error("Request failed", response=request.text)
            raise Exception("Failed to remove config %s from ONOS:  %s" % (url, request.text))

    def uninstall_app(self, o, onos_url, onos_basic_auth):
        log.info("Uninstalling app %s" % o.app_id)
        url = '%s/onos/v1/applications/%s' % (onos_url, o.app_id)

        request = requests.delete(url, auth=onos_basic_auth)

        if request.status_code != 204:
            log.error("Request failed", response=request.text)
            raise Exception("Failed to delete application %s from ONOS: %s" % (url, request.text))

    def deactivate_app(self, o, onos_url, onos_basic_auth):
        log.info("Deactivating app %s" % o.app_id)
        url = '%s/onos/v1/applications/%s/active' % (onos_url, o.app_id)

        request = requests.delete(url, auth=onos_basic_auth)

        if request.status_code != 204:
            log.error("Request failed", response=request.text)
            raise Exception("Failed to deactivate application %s from ONOS: %s" % (url, request.text))

    def delete_record(self, o):

        if hasattr(o, 'service_instance'):
            # this is a ServiceInstanceAttribute model
            if 'ONOSApp' in o.service_instance.leaf_model.class_names:
                return self.delete_config(o)
            return  # if it's not related to an ONOSApp do nothing

        # NOTE if it is an ONOSApp we don't care about the ServiceInstanceAttribute
        # as the reaper will delete it

        # getting onos url and auth
        onos_url = "%s:%s" % (Helpers.format_url(o.owner.leaf_model.rest_hostname), o.owner.leaf_model.rest_port)
        onos_basic_auth = HTTPBasicAuth(o.owner.leaf_model.rest_username, o.owner.leaf_model.rest_password)

        # deactivate an app (bundled in onos)
        if not o.url or o.url is None:
            self.deactivate_app(o, onos_url, onos_basic_auth)
        # uninstall an app from a remote source, only if it has been activated before
        if o.url and o.url is not None:
            self.uninstall_app(o, onos_url, onos_basic_auth)
