/*
 * Copyright 2017-present Open Networking Laboratory
 *
 * 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.
 */
package org.onosproject.l3vpn.netl3vpn.impl;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.config.DynamicConfigEvent;
import org.onosproject.config.DynamicConfigListener;
import org.onosproject.config.DynamicConfigService;
import org.onosproject.core.CoreService;
import org.onosproject.core.IdGenerator;
import org.onosproject.l3vpn.netl3vpn.AccessInfo;
import org.onosproject.l3vpn.netl3vpn.BgpDriverInfo;
import org.onosproject.l3vpn.netl3vpn.BgpInfo;
import org.onosproject.l3vpn.netl3vpn.DeviceInfo;
import org.onosproject.l3vpn.netl3vpn.FullMeshVpnConfig;
import org.onosproject.l3vpn.netl3vpn.HubSpokeVpnConfig;
import org.onosproject.l3vpn.netl3vpn.InterfaceInfo;
import org.onosproject.l3vpn.netl3vpn.NetL3VpnException;
import org.onosproject.l3vpn.netl3vpn.NetL3VpnStore;
import org.onosproject.l3vpn.netl3vpn.VpnConfig;
import org.onosproject.l3vpn.netl3vpn.VpnInstance;
import org.onosproject.l3vpn.netl3vpn.VpnSiteRole;
import org.onosproject.l3vpn.netl3vpn.VpnType;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.DriverService;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev20130715.IetfInetTypes;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.Interfaces;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.IetfL3VpnSvc;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.DefaultL3VpnSvc;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.L3VpnSvc;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.VpnAttachment;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.vpnattachment.AttachmentFlavor;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.vpnattachment.attachmentflavor.DefaultVpnId;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.Sites;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.VpnServices;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.Site;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.SiteNetworkAccesses;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.sitenetworkaccesses.SiteNetworkAccess;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.vpnservices.VpnSvc;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.Bearer;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.DefaultBearer;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.DefaultRequestedType;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.RequestedType;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentipconnection.IpConnection;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siterouting.RoutingProtocols;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siterouting.routingprotocols.RoutingProtocol;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.NetworkInstances;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev20130715.IetfYangTypes;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.L3VpnSvcExt;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.l3vpnsvc.sites.site.sitenetworkaccesses.sitenetworkaccess.bearer.DefaultAugmentedL3VpnBearer;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.l3vpnsvc.sites.site.sitenetworkaccesses.sitenetworkaccess.bearer.requestedtype.DefaultAugmentedL3VpnRequestedType;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.RequestedTypeChoice;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.requestedtypechoice.DefaultDot1Qcase;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.requestedtypechoice.DefaultPhysicalCase;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.DefaultModelObjectData;
import org.onosproject.yang.model.ModelConverter;
import org.onosproject.yang.model.ModelObject;
import org.onosproject.yang.model.ModelObjectData;
import org.onosproject.yang.model.ModelObjectId;
import org.onosproject.yang.model.NodeKey;
import org.onosproject.yang.model.ResourceData;
import org.onosproject.yang.model.ResourceId;
import org.onosproject.yang.model.YangModel;
import org.onosproject.yang.model.YangModuleId;
import org.onosproject.yang.runtime.DefaultAppModuleInfo;
import org.onosproject.yang.runtime.DefaultModelRegistrationParam;
import org.onosproject.yang.runtime.ModelRegistrationParam;
import org.onosproject.yang.runtime.YangModelRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.config.DynamicConfigEvent.Type.NODE_ADDED;
import static org.onosproject.config.DynamicConfigEvent.Type.NODE_DELETED;
import static org.onosproject.l3vpn.netl3vpn.impl.BgpConstructionUtil.createBgpInfo;
import static org.onosproject.l3vpn.netl3vpn.impl.InsConstructionUtil.createInstance;
import static org.onosproject.l3vpn.netl3vpn.impl.IntConstructionUtil.createInterface;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.BEARER_NULL;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.CONS_HUNDRED;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.DEVICE_INFO_NULL;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.EVENT_NOT_SUPPORTED;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.ID_LIMIT;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.ID_LIMIT_EXCEEDED;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.INT_INFO_NULL;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.IP_INT_INFO_NULL;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MG_MT_ADD;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.PORT_NAME;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.SITE_ROLE_NULL;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.SITE_VPN_MISMATCH;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_ATTACHMENT_NULL;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_POLICY_NOT_SUPPORTED;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_TYPE_UNSUPPORTED;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getBgpCreateConfigObj;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIntCreateModObj;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIntNotAvailable;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getMgmtIpUnAvailErr;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForL3VpnSvc;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForSites;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getResourceData;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getRole;
import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnCreateModObj;
import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
import static org.onosproject.yang.runtime.helperutils.YangApacheUtils.getYangModel;

/**
 * The IETF net l3vpn manager implementation.
 * // TODO: Implementation of the manager class.
 */
@Component(immediate = true)
public class NetL3vpnManager {

    private static final String APP_ID = "org.onosproject.app.l3vpn";
    private static final String L3_VPN_ID_TOPIC = "l3vpn-id";
    private static final String ONOS_NET_L3VPN = "onos/netl3vpn";
    private static final String EVENT_HANDLER = "event-handler-%d";

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DriverService driverService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceService deviceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected YangModelRegistry modelRegistry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ModelConverter modelConverter;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DynamicConfigService configService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NetL3VpnStore l3VpnStore;

    protected IdGenerator l3VpnIdGen;

    private DynamicConfigListener configListener = new InternalConfigListener();

    private ModelRegistrationParam regParam;

    private ExecutorService executor = Executors.newSingleThreadExecutor(
            groupedThreads(ONOS_NET_L3VPN, EVENT_HANDLER, log));

    private ResourceId id;
    private ResourceId module;
    private ResourceId sites;

    @Activate
    protected void activate() {
        coreService.registerApplication(APP_ID);
        l3VpnIdGen = coreService.getIdGenerator(L3_VPN_ID_TOPIC);
        registerModel();
        getResourceId();
        configService.addListener(configListener);
        log.info("Started");
    }

    @Deactivate
    protected void deactivate() {
        modelRegistry.unregisterModel(regParam);
        configService.removeListener(configListener);
        log.info("Stopped");
    }

    private void registerModel() {
        YangModel model = getYangModel(getClass());
        Iterator<YangModuleId> it = model.getYangModulesId().iterator();

        //Create model registration param.
        ModelRegistrationParam.Builder b =
                DefaultModelRegistrationParam.builder().setYangModel(model);

        YangModuleId id;
        while (it.hasNext()) {
            id = it.next();
            switch (id.moduleName()) {
                case "ietf-inet-types":
                    b.addAppModuleInfo(id, new DefaultAppModuleInfo(
                            IetfInetTypes.class, null));
                    break;
                case "ietf-l3vpn-svc":
                    b.addAppModuleInfo(id, new DefaultAppModuleInfo(
                            IetfL3VpnSvc.class, null));
                    break;
                case "ietf-yang-types":
                    b.addAppModuleInfo(id, new DefaultAppModuleInfo(
                            IetfYangTypes.class, null));
                    break;
                case "l3vpn-svc-ext":
                    b.addAppModuleInfo(id, new DefaultAppModuleInfo(
                            L3VpnSvcExt.class, null));
                    break;
                default:
                    break;
            }
        }
        regParam = b.build();
        modelRegistry.registerModel(regParam);
    }

    /**
     * Returns id as string. If the id is not in the freed list a new id is
     * generated else the id from the freed list is used.
     *
     * @return id
     */
    private String getIdFromGen() {
        Long value;
        Iterable<Long> freeIds = l3VpnStore.getFreedIdList();
        Iterator<Long> it = freeIds.iterator();
        if (it.hasNext()) {
            value = it.next();
            l3VpnStore.removeIdFromFreeList(value);
        } else {
            value = l3VpnIdGen.getNewId();
        }
        if (value > ID_LIMIT) {
            throw new RuntimeException(ID_LIMIT_EXCEEDED);
        }
        return CONS_HUNDRED + String.valueOf(value);
    }

    /**
     * Returns the resource id, after constructing model object id and
     * converting it.
     */
    private void getResourceId() {

        ModelObjectId moduleId = ModelObjectId.builder().build();
        module = getResourceVal(moduleId);

        ModelObjectId svcId = getModIdForL3VpnSvc();
        id = getResourceVal(svcId);

        ModelObjectId sitesId = getModIdForSites();
        sites = getResourceVal(sitesId);
    }

    /**
     * Returns resource id from model converter.
     *
     * @param modelId model object id
     * @return resource id
     */
    private ResourceId getResourceVal(ModelObjectId modelId) {
        DefaultModelObjectData.Builder data = DefaultModelObjectData.builder()
                .identifier(modelId);
        ResourceData resData = modelConverter.createDataNode(data.build());
        return resData.resourceId();
    }

    /**
     * Processes create request from the store, by taking the root object.
     * The root object is then used for l3VPN processing.
     *
     * @param storeId store resource id
     */
    private void processCreateFromStore(ResourceId storeId) {
        List<ModelObject> objects = getModelObjects(storeId, module);
        for (ModelObject obj : objects) {
            if (obj instanceof DefaultL3VpnSvc) {
                DefaultL3VpnSvc l3VpnSvc = (DefaultL3VpnSvc) obj;
                createGlobalConfig(l3VpnSvc);
            }
        }
    }

    /**
     * Returns model objects of the store. The data node is read from the
     * config store. This returns the resource id's node. So the node's
     * parent resource id is taken and the data node is given to model
     * converter.
     *
     * @param storeId store resource id
     * @param appId   parent resource id
     * @return model objects
     */
    public List<ModelObject> getModelObjects(ResourceId storeId,
                                             ResourceId appId) {
        DataNode dataNode = configService.readNode(storeId, null);
        ResourceData data = getResourceData(dataNode, appId);
        ModelObjectData modelData = modelConverter.createModel(data);
        return modelData.modelObjects();
    }

    /**
     * Returns true if the event resource id points to the root level node
     * only and event is for addition and deletion; false otherwise.
     *
     * @param event config event
     * @return true if event is supported; false otherwise
     */
    public boolean isSupported(DynamicConfigEvent event) {
        ResourceId rsId = event.subject();
        List<NodeKey> storeKeys = rsId.nodeKeys();
        List<NodeKey> regKeys = id.nodeKeys();
        if (storeKeys != null) {
            if (storeKeys.size() == 1) {
                return storeKeys.get(0).equals(regKeys.get(1)) &&
                        (event.type() == NODE_ADDED ||
                                event.type() == NODE_DELETED);
            }
        }
        return false;
    }

    /***
     * Creation of all configuration in standard device model.
     *
     * @param l3VpnSvc l3VPN service object
     */
    void createGlobalConfig(L3VpnSvc l3VpnSvc) {
        if (l3VpnSvc.vpnServices() != null) {
            createVpnServices(l3VpnSvc.vpnServices());
        }
        if (l3VpnSvc.sites() != null) {
            createInterfaceConfig(l3VpnSvc.sites());
        }
    }

    /**
     * Creates the VPN instances from the VPN services object, if only that
     * VPN instance is not already created.
     *
     * @param vpnSvcs VPN services object
     */
    private void createVpnServices(VpnServices vpnSvcs) {
        if (vpnSvcs != null && vpnSvcs.vpnSvc() != null) {
            List<VpnSvc> svcList = vpnSvcs.vpnSvc();
            for (VpnSvc svc : svcList) {
                String vpnName = svc.vpnId().string();
                l3VpnStore.addVpnInsIfAbsent(vpnName, new VpnInstance(vpnName));
            }
        }
    }

    /**
     * Creates interface configuration from the site network access if
     * available.
     *
     * @param sites sites object
     */
    private void createInterfaceConfig(Sites sites) {
        if (sites.site() != null) {
            List<Site> sitesList = sites.site();
            for (Site site : sitesList) {
                if (site.siteNetworkAccesses() != null) {
                    SiteNetworkAccesses accesses = site.siteNetworkAccesses();
                    List<SiteNetworkAccess> accessList =
                            accesses.siteNetworkAccess();
                    for (SiteNetworkAccess access : accessList) {
                        createFromAccess(access, site.siteId().string());
                    }
                }
            }
        }
    }

    /**
     * Creates the interface and VPN related configurations from the access
     * and site id value.
     *
     * @param access site network access
     * @param siteId site id
     */
    private void createFromAccess(SiteNetworkAccess access, String siteId) {
        Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
        Map<String, VpnInstance> insMap = l3VpnStore.getVpnInstances();
        String accessId = access.siteNetworkAccessId().string();
        AccessInfo info = new AccessInfo(siteId, accessId);

        if (intMap.get(info) == null) {
            VpnSiteRole siteRole = getSiteRole(access.vpnAttachment());
            VpnInstance instance = insMap.get(siteRole.name());
            if (instance == null) {
                throw new NetL3VpnException(SITE_VPN_MISMATCH);
            }
            buildFromAccess(instance, info, access, siteRole);
        }
    }

    /**
     * Returns the VPN site role from the VPN attachment.
     *
     * @param attach VPN attachment
     * @return VPN site role
     */
    private VpnSiteRole getSiteRole(VpnAttachment attach) {
        if (attach == null || attach.attachmentFlavor() == null) {
            throw new NetL3VpnException(VPN_ATTACHMENT_NULL);
        }
        AttachmentFlavor flavor = attach.attachmentFlavor();
        if (!(flavor instanceof DefaultVpnId)) {
            throw new NetL3VpnException(VPN_POLICY_NOT_SUPPORTED);
        }
        DefaultVpnId vpnId = (DefaultVpnId) flavor;
        if (vpnId.siteRole() == null) {
            throw new NetL3VpnException(SITE_ROLE_NULL);
        }
        VpnType role = getRole(vpnId.siteRole());
        VpnSiteRole vpnRole = new VpnSiteRole(
                String.valueOf(vpnId.vpnId()), role);
        return vpnRole;
    }

    /**
     * Builds the required details for device standard model from the site
     * network access info available.
     *
     * @param instance VPN instance
     * @param info     access info
     * @param access   network access
     * @param role     VPN site role
     */
    private void buildFromAccess(VpnInstance instance, AccessInfo info,
                                 SiteNetworkAccess access, VpnSiteRole role) {
        Bearer bearer = access.bearer();
        if (bearer == null) {
            throw new NetL3VpnException(BEARER_NULL);
        }

        RequestedType reqType = bearer.requestedType();
        IpConnection connect = access.ipConnection();
        RoutingProtocols pro = access.routingProtocols();

        if (reqType == null || connect == null) {
            throw new NetL3VpnException(IP_INT_INFO_NULL);
        }
        buildDeviceDetails(instance, info, role, bearer, connect,
                           reqType, pro);
    }

    /**
     * Builds the device details such as, VPN instance value if it is for
     * the first time, interface values and BGP info if available in service.
     *
     * @param instance VPN instance
     * @param accInfo  access info
     * @param role     VPN site role
     * @param bearer   bearer object
     * @param connect  ip connect object
     * @param reqType  requested type
     * @param pro      routing protocol
     */
    private void buildDeviceDetails(VpnInstance instance, AccessInfo accInfo,
                                    VpnSiteRole role, Bearer bearer,
                                    IpConnection connect, RequestedType reqType,
                                    RoutingProtocols pro) {
        Map<AccessInfo, InterfaceInfo> interMap = l3VpnStore.getInterfaceInfo();
        InterfaceInfo intInfo = interMap.get(accInfo);
        if (intInfo != null) {
            return;
        }

        DeviceInfo info = buildDevVpnIns(bearer, instance, role, connect);
        String portName = getInterfaceName(info, reqType);
        buildDevVpnInt(info, instance, connect, portName, accInfo);

        if (pro != null && pro.routingProtocol() != null) {
            buildBgpInfo(pro.routingProtocol(), info,
                         role.name(), connect, accInfo);
        }
        InterfaceInfo interInfo = new InterfaceInfo(info, portName,
                                                    instance.vpnName());
        l3VpnStore.addInterfaceInfo(accInfo, interInfo);
    }

    /**
     * Builds device VPN instance with the service objects. It returns
     *
     * @param bearer  bearer object
     * @param ins     VPN instance
     * @param role    VPN site role
     * @param connect ip connection
     * @return return
     */
    private DeviceInfo buildDevVpnIns(Bearer bearer, VpnInstance ins,
                                      VpnSiteRole role, IpConnection connect) {
        DefaultAugmentedL3VpnBearer augBearer = ((DefaultBearer) bearer)
                .augmentation(DefaultAugmentedL3VpnBearer.class);
        DeviceId id = getDeviceId(augBearer);
        Map<DeviceId, DeviceInfo> devices = ins.devInfo();
        DeviceInfo info = null;
        if (devices != null) {
            info = devices.get(id);
        }
        if (info == null) {
            info = createVpnInstance(id, role, ins, connect);
        }
        return info;
    }

    /**
     * Returns the device id from the bearer augment attachment of service.
     * If the attachment in augment is not available it throws error.
     *
     * @param attach augmented bearer
     * @return device id
     */
    private DeviceId getDeviceId(DefaultAugmentedL3VpnBearer attach) {
        if (attach == null || attach.bearerAttachment() == null ||
                attach.bearerAttachment().peMgmtIp() == null ||
                attach.bearerAttachment().peMgmtIp().string() == null) {
            throw new NetL3VpnException(DEVICE_INFO_NULL);
        }
        String ip = attach.bearerAttachment().peMgmtIp().string();
        return getId(ip);
    }

    /**
     * Returns the device id whose management ip address matches with the ip
     * received.
     *
     * @param ip ip address
     * @return device id
     */
    public DeviceId getId(String ip) {
        for (Device device : deviceService.getAvailableDevices()) {
            String val = device.annotations().value(MG_MT_ADD);
            if (ip.equals(val)) {
                return device.id();
            }
        }
        throw new NetL3VpnException(getMgmtIpUnAvailErr(ip));
    }

    /**
     * Creates the VPN instance by constructing standard device model of
     * instances. It adds the RD and RT values to the VPN instance.
     *
     * @param id   device id
     * @param role VPN site role
     * @param inst VPN instance
     * @param ip   ip connection
     * @return device info
     */
    private DeviceInfo createVpnInstance(DeviceId id, VpnSiteRole role,
                                         VpnInstance inst, IpConnection ip) {
        Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
        generateRdRt(inst, role);
        DeviceInfo info = new DeviceInfo(id);
        inst.addDevInfo(id, info);

        NetworkInstances instances = createInstance(inst, role, ip);
        ModelObjectData devMod = getVpnCreateModObj(intMap, instances,
                                                    id.toString());
        ModelObjectData driMod = info.processCreateInstance(driverService,
                                                            devMod);
        ResourceData resData = modelConverter.createDataNode(driMod);
        addToStore(resData);
        return info;
    }

    /**
     * Adds the resource data that is received from the driver, after
     * converting from the model object data.
     *
     * @param resData resource data
     */
    private void addToStore(ResourceData resData) {
        if (resData != null && resData.dataNodes() != null) {
            List<DataNode> dataNodes = resData.dataNodes();
            for (DataNode node : dataNodes) {
                configService.createNodeRecursive(resData.resourceId(), node);
            }
        }
    }

    /**
     * Generates RD and RT value for the VPN instance for the first time VPN
     * instance creation.
     *
     * @param ins  VPN instance
     * @param role VPN site role
     */
    private void generateRdRt(VpnInstance ins, VpnSiteRole role) {
        ins.type(role.role());
        VpnConfig config = ins.vpnConfig();
        String rd = null;
        if (config == null) {
            rd = getIdFromGen();
        }
        switch (ins.type()) {
            case ANY_TO_ANY:
                if (config == null) {
                    config = new FullMeshVpnConfig(rd);
                    config.rd(rd);
                }
                break;

            case HUB:
            case SPOKE:
                if (config == null) {
                    config = new HubSpokeVpnConfig();
                    config.rd(rd);
                }
                createImpRtVal((HubSpokeVpnConfig) config, ins.type());
                createExpRtVal((HubSpokeVpnConfig) config, ins.type());
                break;

            default:
                throw new NetL3VpnException(VPN_TYPE_UNSUPPORTED);
        }
        ins.vpnConfig(config);
    }

    /**
     * Creates import RT value for HUB and SPOKE, according to the type, if
     * the values are not present.
     *
     * @param config VPN config
     * @param type   VPN type
     */
    private void createImpRtVal(HubSpokeVpnConfig config, VpnType type) {
        if (type == HUB) {
            if (config.hubImpRt() != null) {
                return;
            }
            setHubImpRt(config);
        } else {
            if (config.spokeImpRt() != null) {
                return;
            }
            config.spokeImpRt(config.rd());
        }
    }

    /**
     * Sets the HUB import RT, from the spoke export RT. If it is not
     * available a new ID is generated.
     *
     * @param config VPN config
     */
    public void setHubImpRt(HubSpokeVpnConfig config) {
        String hubImp;
        if (config.spokeExpRt() != null) {
            hubImp = config.spokeExpRt();
        } else {
            hubImp = getIdFromGen();
        }
        config.hubImpRt(hubImp);
    }

    /**
     * Creates export RT value for HUB and SPOKE, according to the type, if
     * the values are not present.
     *
     * @param config VPN config
     * @param type   VPN type
     */
    private void createExpRtVal(HubSpokeVpnConfig config, VpnType type) {
        if (type == HUB) {
            if (config.hubExpRt() != null) {
                return;
            }
            config.hubExpRt(config.rd());
        } else {
            if (config.spokeExpRt() != null) {
                return;
            }
            setSpokeExpRt(config);
        }
    }

    /**
     * Sets the SPOKE export RT, from the hub import RT. If it is not
     * available a new ID is generated.
     *
     * @param config VPN config
     */
    public void setSpokeExpRt(HubSpokeVpnConfig config) {
        String spokeExp;
        if (config.hubImpRt() != null) {
            spokeExp = config.hubImpRt();
        } else {
            spokeExp = getIdFromGen();
        }
        config.spokeExpRt(spokeExp);
    }

    /**
     * Returns the interface name from the requested type service object.
     *
     * @param info    device info
     * @param reqType requested type
     * @return interface name
     */
    private String getInterfaceName(DeviceInfo info, RequestedType reqType) {
        DefaultAugmentedL3VpnRequestedType req =
                ((DefaultRequestedType) reqType).augmentation(
                        DefaultAugmentedL3VpnRequestedType.class);
        if (req == null || req.requestedTypeProfile() == null ||
                req.requestedTypeProfile().requestedTypeChoice() == null) {
            throw new NetL3VpnException(INT_INFO_NULL);
        }
        RequestedTypeChoice reqChoice = req.requestedTypeProfile()
                .requestedTypeChoice();
        return getNameFromChoice(reqChoice, info.deviceId());
    }

    /**
     * Returns the interface name from the type choice provided.
     *
     * @param choice service choice
     * @param id     device id
     * @return interface name
     */
    private String getNameFromChoice(RequestedTypeChoice choice, DeviceId id) {
        if (choice == null) {
            throw new NetL3VpnException(INT_INFO_NULL);
        }
        String intName;
        if (choice instanceof DefaultDot1Qcase) {
            if (((DefaultDot1Qcase) choice).dot1q() == null ||
                    ((DefaultDot1Qcase) choice).dot1q()
                            .physicalIf() == null) {
                throw new NetL3VpnException(INT_INFO_NULL);
            }
            intName = ((DefaultDot1Qcase) choice).dot1q().physicalIf();
        } else {
            if (((DefaultPhysicalCase) choice).physical() == null ||
                    ((DefaultPhysicalCase) choice).physical()
                            .physicalIf() == null) {
                throw new NetL3VpnException(INT_INFO_NULL);
            }
            intName = ((DefaultPhysicalCase) choice).physical().physicalIf();
        }
        return getPortName(intName, id);
    }

    /**
     * Returns the port name when it the port is available in the device.
     *
     * @param intName interface name
     * @param id      device id
     * @return port name
     */
    private String getPortName(String intName, DeviceId id) {
        List<Port> ports = deviceService.getPorts(id);
        for (Port port : ports) {
            String pName = port.annotations().value(PORT_NAME);
            if (pName.equals(intName)) {
                return intName;
            }
        }
        throw new NetL3VpnException(getIntNotAvailable(intName));
    }

    /**
     * Builds the interface for the device binding with the VPN instance.
     *
     * @param info    device info
     * @param ins     VPN instance
     * @param connect IP connection
     * @param pName   port name
     * @param access  access info
     */
    private void buildDevVpnInt(DeviceInfo info, VpnInstance ins,
                                IpConnection connect, String pName,
                                AccessInfo access) {
        Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
        info.addAccessInfo(access);
        info.addIfName(pName);
        Interfaces interfaces = createInterface(pName, ins.vpnName(),
                                                connect);
        ModelObjectData devMod = getIntCreateModObj(
                intMap, interfaces, info.deviceId().toString());
        ModelObjectData driMod = info.processCreateInterface(driverService,
                                                             devMod);
        ResourceData resData = modelConverter.createDataNode(driMod);
        addToStore(resData);
    }

    /**
     * Builds the BGP information from the routes that are given from the
     * service.
     *
     * @param routes  routing protocol
     * @param info    device info
     * @param name    VPN name
     * @param connect IP connection
     * @param access  access info
     */
    private void buildBgpInfo(List<RoutingProtocol> routes, DeviceInfo info,
                              String name, IpConnection connect,
                              AccessInfo access) {
        Map<BgpInfo, DeviceId> bgpMap = l3VpnStore.getBgpInfo();
        BgpInfo intBgp = createBgpInfo(routes, info, name, connect, access);
        if (intBgp != null) {
            intBgp.vpnName(name);
            BgpDriverInfo config = getBgpCreateConfigObj(
                    bgpMap, info.deviceId().toString());
            ModelObjectData driData = info.processCreateBgpInfo(
                    driverService, intBgp, config);
            l3VpnStore.addBgpInfo(info.bgpInfo(), info.deviceId());
            ResourceData resData = modelConverter.createDataNode(driData);
            addToStore(resData);
        }
    }

    /**
     * Representation of internal listener, listening for dynamic config event.
     */
    private class InternalConfigListener implements DynamicConfigListener {

        @Override
        public boolean isRelevant(DynamicConfigEvent event) {
            return isSupported(event);
        }

        @Override
        public void event(DynamicConfigEvent event) {
            executor.execute(() -> {
                try {
                    ResourceId rsId = event.subject();
                    switch (event.type()) {
                        case NODE_ADDED:
                            processCreateFromStore(rsId);
                            break;

                        case NODE_DELETED:
                            //TODO: To be committed.
                            break;

                        default:
                            throw new NetL3VpnException(EVENT_NOT_SUPPORTED);
                    }
                } catch (Exception e) {
                    log.warn("Failed to process {}", event, e);
                }
            });
        }
    }
}
