# Copyright 2014-2015 National Institute of Advanced Industrial Science and Technology
#
# 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 eisoil.core
#import eisoil.core.log
#logger = eisoil.core.log.getLogger('tnrmgeniv3delegate')
#logger = eisoil.core.log.getLogger('tnrm-config')

from xml.etree.ElementTree import *
from tn_rm_exceptions import ManagerException, ParamException, RspecException
from vlanManager import *

# from tn_rm_delegate import logger
import log
logger = log.getLogger('tnrm:config')
logger.info("config: ready")

isRead = False

advertisement_rspec = """<?xml version="1.1" encoding="UTF-8"?>
<rspec type="advertisement"
       xmlns="http://www.geni.net/resources/rspec/3"
       xmlns:sharedvlan="http://www.geni.net/resources/rspec/ext/shared-vlan/1"
       xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
       xs:schemaLocation="http://www.geni.net/resources/rspec/3/ad.xsd
                          http://www.geni.net/resources/rspec/ext/shared-vlan/1/ad.xsd">

"""
close_rspec = '</rspec>\n'
space4 = "    "
default_type = "NSI"

#
dict_nodes = {}
dict_interfaces = {}
dict_nsi_stps = {}
dict_felix_stps = {}
#

class Config:
    def __init__(self, file):
        self.advertisement = ""
        # tree = fromstring(text)
        tree = parse(file)
        elem = tree.getroot()
        
        # elem = elem.find("resources")
        for node in elem.findall("node"):
            component_id = node.get("component_id")
            manager_id = node.get("component_manager_id")
            isExclusive = node.get("exclusive")
            #
            # print "add node id=" + component_id
            cnode = Node(component_id, manager_id, isExclusive, dict_felix_stps)
            
            for ifs in node.findall("interface"):
                felix_domain_id = ifs.get("felix_domain_id")
                felix_stp_id = ifs.get("felix_stp_id")
                nsi_stp_id = ifs.get("nsi_stp_id")
                # nsi_stp_id_in = ifs.get("nsi_stp_id_in")
                # nsi_stp_id_out = ifs.get("nsi_stp_id_out")
                vlans = ifs.get("vlan")
                capacity = ifs.get("capacity")
                #
                # cinterface = Interface(cnode, felix_domain_id, felix_stp_id, nsi_stp_id, nsi_stp_id_in, nsi_stp_id_out, vlans, capacity)
                cinterface = Interface(cnode, felix_domain_id, felix_stp_id, nsi_stp_id, vlans, capacity)
                cinterface.component_id = "%s+%s" % (felix_domain_id, felix_stp_id)
                #
                gre_type = ifs.get("type")
                gre_address = ifs.get("address")
                gre_sedev = ifs.get("sedev")
                # gre_ofport = ifs.get("ofport")
                # gre_brname = ifs.get("brname")
                gre_dpid = ifs.get("dpid")
                gre_ovsdb = ifs.get("ovsdb")
                gre_ryu = ifs.get("ryu")

                if (gre_type is not None and gre_type != default_type):
                    try:
                        # print "gre_dpid=" + gre_dpid
                        gre_dpid_i = int(gre_dpid)
                    except:
                        # try base 16
                        try:
                            gre_dpid_i = int(gre_dpid, 16)
                        except Exception as e:
                            raise ParamException("config:", "%s is not DPID_PATTERN or Integer" % (gre_dpid))

                    gre_dpid = "%016x" % gre_dpid_i
                    # print "gre_dpid=" + gre_dpid

                    # cinterface.set(gre_type, gre_address, gre_ofdev, gre_ofport, gre_brname, gre_dpid, 
                    #                gre_ovsdb, gre_ryu)
                    cinterface.set(gre_type, gre_address, gre_dpid, gre_ovsdb, gre_ryu, gre_sedev)
                    # print "**** %s" % (cinterface)
                dict_felix_stps[cinterface.component_id] = cinterface

    def get_advertisement(self):
        s = advertisement_rspec
        for cnode in dict_nodes.values():
            s += cnode.get_open_advertisement();

            for ifs in cnode.interfaces.values():
                s += ifs.get_advertisement()
            
            s += cnode.get_close_advertisement();

        s += close_rspec
        self.advertisement = s
        return self.advertisement

    def get_nsi_stp(self, id):
        if id in dict_felix_stps:
            interface = dict_felix_stps[id]
            return interface.nsi_stp_id
        raise ParamException("config:", "%s is not exist in config.xml." % (id))

    def get_node(self, id):
        if (isinstance(id, type(None))):
            raise ParamException("config:", "Node Component Id is None.")

        try:
            tnode = dict_nodes[id]
            if (isinstance(tnode, type(None))):
                raise ParamException("config:", "Node Component Id does not exist. Id=%s" % id)
            else:
                return tnode
        except KeyError:
            print "Node Component Id does not exist. Id=%s" % id
        return  None

    def get_interface(self, id):
        if (isinstance(id, type(None))):
            raise ParamException("config:", "Node Component Id is None.")
        try:
            ifs = dict_interfaces[id]
            if (isinstance(ifs, type(None))):
                raise ParamException("config:", "Interface Component Id does not exist. Id=%s" % id)
            else:
                return ifs
        except KeyError:
            print "Interface Component Id does not exist. Id=%s" % id
        return  None

    def get_stp(self, id):
        if (isinstance(id, type(None))):
            raise ParamException("config:", "Node Component Id is None.")
        try:
            ifs = dict_interfaces[id]
            if (isinstance(ifs, type(None))):
                raise ParamException("config:", "Interface Component Id does not exist. Id=%s" % id)
            else: