/*
 * 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.cluster.ClusterService;
import org.onosproject.cluster.LeadershipEvent;
import org.onosproject.cluster.LeadershipEventListener;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
import org.onosproject.config.DynamicConfigEvent;
import org.onosproject.config.DynamicConfigListener;
import org.onosproject.config.DynamicConfigService;
import org.onosproject.core.ApplicationId;
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.VpnType.HUB;
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.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;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected LeadershipService leadershipService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ClusterService clusterService;

    protected IdGenerator l3VpnIdGen;
    private NodeId localNodeId;
    private ApplicationId appId;

    private DynamicConfigListener configListener = new InternalConfigListener();

    private final InternalLeadershipListener leadershipEventListener =
            new InternalLeadershipListener();

    private ModelRegistrationParam regParam;

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

    private ResourceId id;
    private ResourceId module;
    private ResourceId sites;
    private boolean isElectedLeader = false;
    private boolean isActivatedLeader = false;

    @Activate
    protected void activate() {
        appId = coreService.registerApplication(APP_ID);
        l3VpnIdGen = coreService.getIdGenerator(L3_VPN_ID_TOPIC);

        localNodeId = clusterService.getLocalNode().id();

        leadershipService.addListener(leadershipEventListener);
        leadershipService.runForLeadership(appId.name());

        registerModel();
        getResourceId();
        configService.addListener(configListener);
        log.info("Started");
    }

    @Deactivate
    protected void deactivate() {
        modelRegistry.unregisterModel(regParam);
        configService.removeListener(configListener);

        leadershipService.withdraw(appId.name());
        leadershipService.removeListener(leadershipEventListener);

        log.info("Stopped");
    }

    private void registerModel() {
        YangModel model = getYangModel(IetfInetTypes.class);
        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());
        //TODO: change this when yang runtime manager implements model
        // converter api.
        return null;
    }

    /**
     * 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) {
        if (isElectedLeader && isActivatedLeader) {
            List<ModelObject> objects = getModelObjects(storeId, module);
            for (ModelObject obj : objects) {
                if (obj instanceof DefaultL3VpnSvc) {
                    DefaultL3VpnSvc l3VpnSvc = (DefaultL3VpnSvc) obj;
                    createGlobalConfig(l3VpnSvc);
                }
            }
        }
    }

    /**
     * Processes delete 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 processDeleteFromStore(ResourceId storeId) {
        if (isElectedLeader && isActivatedLeader) {
            //TODO: add delete logic here.
        }
    }

    /**
     * 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);
                }
            });
        }
    }

    /**
     * Signals that the leadership has changed.
     *
     * @param isLeader true if this instance is now the leader, otherwise false
     */
    private void leaderChanged(boolean isLeader) {
        log.debug("Leader changed: {}", isLeader);

        if (!isLeader) {
            isElectedLeader = false;
            isActivatedLeader = false;
            // Nothing to do
            return;
        }
        isActivatedLeader = false;
        isElectedLeader = true;
    }

    /**
     * A listener for leadership events.
     */
    private class InternalLeadershipListener implements LeadershipEventListener {

        @Override
        public boolean isRelevant(LeadershipEvent event) {
            return event.subject().topic().equals(appId.name());
        }

        @Override
        public void event(LeadershipEvent event) {
            switch (event.type()) {
                case LEADER_CHANGED:
                case LEADER_AND_CANDIDATES_CHANGED:
                    if (localNodeId.equals(event.subject().leaderNodeId())) {
                        log.info("Net l3vpn manager gained leadership");
                        leaderChanged(true);
                    } else {
                        log.info("Net l3vpn manager leader changed. New " +
                                         "leader is {}", event.subject()
                                         .leaderNodeId());
                        leaderChanged(false);
                    }
                default:
                    break;
            }
        }
    }
}
