
# 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 base64
import jinja2
import json
from synchronizers.new_base.modelaccessor import *
from synchronizers.new_base.policy import Policy

from xosconfig import Config
from multistructlog import create_logger

log = create_logger(Config().get('logging'))

class SimpleExampleServiceInstancePolicy(Policy):
    model_name = "SimpleExampleServiceInstance"

    def handle_create(self, service_instance):
        return self.handle_update(service_instance)

    def render_index(self, service_instance):
        service = service_instance.owner.leaf_model

        fields = {}
        fields['tenant_message'] = service_instance.tenant_message
        fields['service_message'] = service.service_message

        if service_instance.foreground_color:
            fields["foreground_color"] = service_instance.foreground_color.html_code

        if service_instance.background_color:
            fields["background_color"] = service_instance.background_color.html_code

        images=[]
        for image in service_instance.embedded_images.all():
            images.append({"name": image.name,
                           "url": image.url})
        fields["images"] = images

        template_fn = os.path.join(os.path.abspath(os.path.dirname(os.path.realpath(__file__))), "index.html.j2")
        template = jinja2.Template(open(template_fn).read())

        return template.render(fields)

    def handle_update(self, service_instance):
        if not service_instance.compute_instance:
            # TODO: Break dependency
            compute_service = KubernetesService.objects.first()
            compute_service_instance_class = Service.objects.get(id=compute_service.id).get_service_instance_class()

            exampleservice = service_instance.owner.leaf_model

            # TODO: What if there is the wrong number of slices?
            slice = exampleservice.slices.first()

            # TODO: What if there is no default image?
            image = slice.default_image

            name="simpleexampleserviceinstance-%s" % service_instance.id
            compute_service_instance = compute_service_instance_class(slice=slice, owner=compute_service, image=image, name=name, no_sync=True)
            compute_service_instance.save()

            # Create a configmap and attach it to the compute instance
            data = {"index.html": self.render_index(service_instance)}
            cfmap = KubernetesConfigMap(name="simpleexampleserviceinstance-map-%s" % service_instance.id,
                                      trust_domain=slice.trust_domain,
                                      data=json.dumps(data))
            cfmap.save()
            cfmap_mnt = KubernetesConfigVolumeMount(config=cfmap,
                                                    service_instance=compute_service_instance,
                                                    mount_path="/usr/local/apache2/htdocs")
            cfmap_mnt.save()

            # Create a secret and attach it to the compute instance
            data = {"service_secret.txt": base64.b64encode(str(exampleservice.service_secret)),
                    "tenant_secret.txt": base64.b64encode(str(service_instance.tenant_secret))}
            secret = KubernetesSecret(name="simpleexampleserviceinstance-secret-%s" % service_instance.id,
                                      trust_domain=slice.trust_domain,
                                      data=json.dumps(data))
            secret.save()
            secret_mnt = KubernetesSecretVolumeMount(secret=secret, service_instance=compute_service_instance, mount_path="/usr/local/apache2/secrets")
            secret_mnt.save()

            compute_service_instance.no_sync = False
            compute_service_instance.save(update_fields=["no_sync"])

            service_instance.compute_instance = compute_service_instance
            service_instance.save(update_fields=["compute_instance"])
        else:
            compute_instance = service_instance.compute_instance
            mnt = compute_instance.leaf_model.kubernetes_config_volume_mounts.first()
            config = mnt.config
            new_data = json.dumps({"index.html": self.render_index(service_instance)})
            if (new_data != config.data):
                config.data = new_data
                config.save(always_update_timestamp=True)
                # Force the Kubernetes syncstep
                compute_instance.save(always_update_timestamp=True)

    def handle_delete(self, service_instance):
        log.info("handle_delete")
        if service_instance.compute_instance:
            log.info("has a compute_instance")
            service_instance.compute_instance.delete()
            service_instance.compute_instance = None
            # TODO: I'm not sure we can save things that are being deleted...
            service_instance.save(update_fields=["compute_instance"])
