
# 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 os
import base64
from synchronizers.swarm.swarmsyncstep import SwarmSyncStep
from synchronizers.new_base.syncstep import *
from synchronizers.new_base.ansible_helper import *
from synchronizers.new_base.modelaccessor import * 
from xos.logger import observer_logger as logger 
import synchronizers.swarm.swarmlog as slog 


class SyncControllerImages(SwarmSyncStep):
    provides = [ControllerImages]
    observes = ControllerImages
    requested_interval = 0
    playbook='sync_controller_images.yaml' 

    def fetch_pending(self, deleted):
        return super(SyncControllerImages, self).fetch_pending(deleted) 

    def map_sync_inputs(self, controller_image):
        swarm_manager_url = controller_image.controller.auth_url
        (swarm_manager_address, docker_registry_port) = swarm_manager_url.split(':')
        slog.debug("swarm_manager_address: %s    docker_registry_port: %s" 
                    % (swarm_manager_address, docker_registry_port)) 

        input_fields = {
                        'swarm_manager_address' : swarm_manager_address,
                        'docker_registry_port'  : docker_registry_port,
                        'image_file_path'       : controller_image.image.path,
                        'image_dir'             : os.path.dirname(controller_image.image.path),
                        'image_name'            : controller_image.image.name,
                        'image_tag'             : controller_image.image.tag, 
                        'delete'                : False,
                        'ansible_tag'           : '%s@%s' % (
                                                    controller_image.image.name,
                                                    controller_image.controller.name)  # name of ansible playbook
                        } 
        slog.debug("input_fields: %s" % str(input_fields))

        return input_fields 

    def map_sync_outputs(self, controller_image, res):
        slog.debug("Ansible playbook result: %s" % str(res))
        slog.debug("Ansible playbook result[4]['image']['Id']: %s" % str(res[4]['image']['Id']))
        controller_image.glance_image_id = str(res[4]['image']['Id'])
        if len(controller_image.glance_image_id) > 2:
            controller_image.backend_status = '1 - OK'
        else:
            controller_image.backend_status = '2 - Ansible playbook failure'
        controller_image.save() 

    def map_delete_inputs(self, controller_image):
        try:
            controller_register = json.loads(instance.node.site_deployment.controller.backend_register)
            slog.debug("controller_register: %s" % controller_register)

            if (controller_register.get('disabled', False)):
                slog.info('Controller %s is disabled' % instance.node.site_deployment.controller.name)
                raise InnocuousException('Controller %s is disabled' % instance.node.site_deployment.controller.name) 
            
            swarm_manager_url = controller_image.controller.auth_url
            (swarm_manager_address, docker_registry_port) = swarm_manager_url.split(':')
            slog.info("swarm_manager_address: %s    docker_registry_port: %s" % 
                        (swarm_manager_address, docker_registry_port)) 

            input_fields = {
                            'swarm_manager_address' : swarm_manager_address,
                            'docker_registry_port'  : docker_registry_port,
                            'image_file_path'       : controller_image.image.path,
                            'image_dir'             : os.path.dirname(controller_image.image.path),
                            'image_name'            : controller_image.image.name,
                            'image_tag'             : controller_image.image.tag, 
                            'delete'                : True,
                            'ansible_tag'           : '%s@%s' % (
                                                        controller_image.image.name,
                                                        controller_image.controller.name)  # name of ansible playbook
                            } 
            slog.debug("input_fields: %s" % str(input_fields))
            return input_fields 
        except Exception as ex:
            slog.error("Exception: %s   %s   %s" % (type(ex), str(ex), ex.args))
            slog.error("%s" % str(traceback.format_exc()))

