
# 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 requests
from requests.auth import HTTPBasicAuth
from synchronizers.new_base.syncstep import SyncStep, model_accessor
from synchronizers.new_base.modelaccessor import FabricService, Switch

from xosconfig import Config
from multistructlog import create_logger

from helpers import Helpers

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

class SyncFabricSwitch(SyncStep):
    provides = [Switch]
    observes = Switch

    def sync_record(self, model):
        log.info("Adding switch %s to onos-fabric" % model.name)
        # Send device info to onos-fabric netcfg
        data = {
          "devices": {
            model.ofId: {
              "basic": {
                "name": model.name,
                "driver": model.driver
              },
              "segmentrouting" : {
                "name" : model.name,
                "ipv4NodeSid" : model.ipv4NodeSid,
                "ipv4Loopback" : model.ipv4Loopback,
                "routerMac" : model.routerMac,
                "isEdgeRouter" : model.isEdgeRouter,
                "adjacencySids" : []
              }
            }
          }
        }

        onos = Helpers.get_onos_fabric_service()

        url = 'http://%s:%s/onos/v1/network/configuration/' % (onos.rest_hostname, onos.rest_port)
        r = requests.post(url, json=data, auth=HTTPBasicAuth(onos.rest_username, onos.rest_password))

        if r.status_code != 200:
            log.error(r.text)
            raise Exception("Failed to add device %s into ONOS" % model.name)
        else:
            try:
                print r.json()
            except Exception:
                print r.text

    def delete_record(self, model):
        log.info("Removing switch %s from onos-fabric" % model.name)
        onos = Helpers.get_onos_fabric_service()
        url = 'http://%s:%s/onos/v1/network/configuration/devices/%s' % (
        onos.rest_hostname, onos.rest_port, model.ofId)

        r = requests.delete(url, auth=HTTPBasicAuth(onos.rest_username, onos.rest_password))

        if r.status_code != 204:
            log.error(r.text)
            raise Exception("Failed to remove switch %s from ONOS" % model.name)
