/*
 * 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.onosproject.l3vpn.netl3vpn.AccessInfo;
import org.onosproject.l3vpn.netl3vpn.BgpDriverInfo;
import org.onosproject.l3vpn.netl3vpn.BgpInfo;
import org.onosproject.l3vpn.netl3vpn.InterfaceInfo;
import org.onosproject.l3vpn.netl3vpn.NetL3VpnException;
import org.onosproject.l3vpn.netl3vpn.VpnType;
import org.onosproject.net.DeviceId;
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.DefaultL3VpnSvc;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.SiteRole;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.DefaultSites;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.DefaultDevices;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.Devices;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.DefaultDevice;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.Device;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.DeviceKeys;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.NetworkInstances;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.DefaultModelObjectData;
import org.onosproject.yang.model.InnerModelObject;
import org.onosproject.yang.model.ModelObjectData;
import org.onosproject.yang.model.ModelObjectId;
import org.onosproject.yang.model.ResourceData;
import org.onosproject.yang.model.ResourceId;
import org.onosproject.yang.model.DefaultResourceData;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.DEVICE;
import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.DEVICES;
import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.ROOT;
import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.VPN;
import static org.onosproject.l3vpn.netl3vpn.VpnType.ANY_TO_ANY;
import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
import static org.onosproject.l3vpn.netl3vpn.VpnType.SPOKE;

/**
 * Representation of utility for YANG tree builder.
 */
public final class NetL3VpnUtil {

    /**
     * Error message for site VPN name being not present in global VPN.
     */
    static final String SITE_VPN_MISMATCH = "Site VPN instance name did not " +
            "match any of the global VPN names";

    /**
     * Error message for VPN attachment object being null.
     */
    static final String VPN_ATTACHMENT_NULL = "The VPN attachment information" +
            " cannot be null";

    /**
     * Error message for VPN policy being not supported.
     */
    static final String VPN_POLICY_NOT_SUPPORTED = "VPN policy implementation" +
            " is not supported.";

    /**
     * Static constant value for hundred.
     */
    static final String CONS_HUNDRED = "100:";

    /**
     * Error message for site role being not present in site network access.
     */
    static final String SITE_ROLE_NULL = "There must be a site role available" +
            " for the VPN in site network access.";

    /**
     * Error message for bearer object information being null.
     */
    static final String BEARER_NULL = "The bearer information of the access " +
            "is not available";

    /**
     * Error message for requested type or ip connect being null.
     */
    static final String IP_INT_INFO_NULL = "The required information of " +
            "request type or ip connection is not available";

    /**
     * Error message for device info being not available from augment.
     */
    static final String DEVICE_INFO_NULL = "Bearer of site does not have any " +
            "device information in the augment info.";

    /**
     * Static constant value for ip address.
     */
    static final String IP = "ipaddress";

    /**
     * Error message for VPN type being not supported.
     */
    static final String VPN_TYPE_UNSUPPORTED = "The VPN type is not supported";

    /**
     * Error message when the generated ID has crossed the limit.
     */
    static final String ID_LIMIT_EXCEEDED = "The ID generation has got " +
            "exceeded";

    /**
     * Static constant value ID management limit.
     */
    static final Long ID_LIMIT = 4294967295L;

    /**
     * Error message for interface information being not available.
     */
    static final String INT_INFO_NULL = "Requested type does not have any " +
            "interface information in the augment info.";

    /**
     * Static constant value of port name.
     */
    static final String PORT_NAME = "portName";

    /**
     * Static constants to use with accumulator for maximum number of events.
     */
    static final int MAX_EVENTS = 1000;

    /**
     * Static constants to use with accumulator for maximum number of millis.
     */
    static final int MAX_BATCH_MS = 5000;

    /**
     * Static constants to use with accumulator for maximum number of idle
     * millis.
     */
    static final int MAX_IDLE_MS = 1000;

    /**
     * Static constants for timer name.
     */
    static final String TIMER = "dynamic-config-l3vpn-timer";

    /**
     * Error message for unknown event being occurred.
     */
    static final String UNKNOWN_EVENT = "NetL3VPN listener: unknown event: {}";

    /**
     * Error message for event being null.
     */
    static final String EVENT_NULL = "Event cannot be null";

    private static final String SITE_ROLE_INVALID = "The given site role is " +
            "invalid";
    private static final String ANY_TO_ANY_ROLE = "AnyToAnyRole";
    private static final String HUB_ROLE = "HubRole";
    private static final String SPOKE_ROLE = "SpokeRole";

    // No instantiation.
    private NetL3VpnUtil() {
    }

    /**
     * Returns the model object id for service L3VPN container.
     *
     * @return model object id
     */
    static ModelObjectId getModIdForL3VpnSvc() {
        return ModelObjectId.builder().addChild(DefaultL3VpnSvc.class).build();
    }

    /**
     * Returns the model object id for service sites container.
     *
     * @return model object id
     */
    static ModelObjectId getModIdForSites() {
        return ModelObjectId.builder().addChild(DefaultL3VpnSvc.class)
                .addChild(DefaultSites.class).build();
    }

    /**
     * Returns the resource data from the data node and the resource id.
     *
     * @param dataNode data node
     * @param resId    resource id
     * @return resource data
     */
    static ResourceData getResourceData(DataNode dataNode, ResourceId resId) {
        return DefaultResourceData.builder().addDataNode(dataNode)
                .resourceId(resId).build();
    }

    /**
     * Returns the VPN role from the service site role.
     *
     * @param siteRole service site role
     * @return VPN type
     */
    static VpnType getRole(Class<? extends SiteRole> siteRole) {
        switch (siteRole.getSimpleName()) {
            case ANY_TO_ANY_ROLE:
                return ANY_TO_ANY;

            case HUB_ROLE:
                return HUB;

            case SPOKE_ROLE:
                return SPOKE;

            default:
                throw new NetL3VpnException(SITE_ROLE_INVALID);
        }
    }

    /**
     * Returns error message for management ip being unavailable in device.
     *
     * @param ip management ip
     * @return error message
     */
    static String getMgmtIpUnAvailErr(String ip) {
        return "The device with management ip " + ip + " is not available.";
    }

    /**
     * Returns true if device id present in the interface map; false otherwise.
     *
     * @param info interface map
     * @param id   device id
     * @return true if device id available; false otherwise
     */
    private static boolean isDevIdPresent(Map<AccessInfo, InterfaceInfo> info,
                                          String id) {
        for (Map.Entry<AccessInfo, InterfaceInfo> inter : info.entrySet()) {
            InterfaceInfo interfaceInfo = inter.getValue();
            DeviceId devId = interfaceInfo.devInfo().deviceId();
            if (devId.toString().equals(id)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Builds the device model VPN instance model object data, with respect to
     * the device level.
     *
     * @param id  device id
     * @param ins VPN instance
     * @return model object data, with device level
     */
    private static ModelObjectData buildInsModDataDevice(String id,
                                                         NetworkInstances ins) {
        DeviceKeys devKeys = new DeviceKeys();
        devKeys.deviceid(id);
        ModelObjectId modelId = ModelObjectId.builder()
                .addChild(DefaultDevices.class)
                .addChild(DefaultDevice.class, devKeys)
                .build();
        return DefaultModelObjectData.builder().identifier(modelId)
                .addModelObject((InnerModelObject) ins).build();
    }

    /**
     * Builds the device model VPN instance model object data, with respect to
     * the devices level.
     *
     * @param id  device id
     * @param ins VPN instance
     * @return model object data, with devices level
     */
    private static ModelObjectData buildInsModDataDevices(String id,
                                                          NetworkInstances ins) {
        ModelObjectId modelId = ModelObjectId.builder()
                .addChild(DefaultDevices.class).build();
        Device device = new DefaultDevice();
        device.deviceid(id);
        device.networkInstances(ins);
        return DefaultModelObjectData.builder().identifier(modelId)
                .addModelObject((InnerModelObject) device).build();
    }

    /**
     * Builds the device model VPN instance model object data, with respect to
     * root level.
     *
     * @param id  device id
     * @param ins VPN instance
     * @return model object data, with root level
     */
    private static ModelObjectData buildInsModDataRoot(String id,
                                                       NetworkInstances ins) {
        Devices devices = new DefaultDevices();
        Device device = new DefaultDevice();
        List<Device> deviceList = new LinkedList<>();
        device.deviceid(id);
        device.networkInstances(ins);
        deviceList.add(device);
        devices.device(deviceList);
        return DefaultModelObjectData.builder()
                .addModelObject((InnerModelObject) devices).build();
    }

    /**
     * Builds the device model interface model object data, with respect to
     * device level.
     *
     * @param id  device id
     * @param ifs interface object
     * @return model object data, with device level
     */
    private static ModelObjectData buildIntModDataDevice(String id,
                                                         Interfaces ifs) {
        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
                .rev20140508.ietfinterfaces.devices.DeviceKeys keys =
                new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang
                        .ietf.interfaces.rev20140508.ietfinterfaces.devices
                        .DeviceKeys();
        keys.deviceid(id);
        ModelObjectId modelId = ModelObjectId.builder()
                .addChild(org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns
                                  .yang.ietf.interfaces.rev20140508
                                  .ietfinterfaces.DefaultDevices.class)
                .addChild(org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns
                                  .yang.ietf.interfaces.rev20140508
                                  .ietfinterfaces.devices.DefaultDevice.class,
                          keys)
                .build();
        return DefaultModelObjectData.builder().identifier(modelId)
                .addModelObject((InnerModelObject) ifs).build();
    }

    /**
     * Returns the VPN instance create model object data.
     *
     * @param intMap    interface map
     * @param instances VPN instances
     * @param id        device id
     * @return VPN instance model object data
     */
    static ModelObjectData getVpnCreateModObj(Map<AccessInfo, InterfaceInfo> intMap,
                                              NetworkInstances instances,
                                              String id) {
        ModelObjectData modData;
        boolean devAdded = isDevIdPresent(intMap, id);
        if (devAdded) {
            modData = buildInsModDataDevice(id, instances);
        } else if (intMap.size() != 0) {
            modData = buildInsModDataDevices(id, instances);
        } else {
            modData = buildInsModDataRoot(id, instances);
        }
        return modData;
    }

    /**
     * Returns error message for interface being unavailable in device.
     *
     * @param intName interface name
     * @return error message
     */
    static String getIntNotAvailable(String intName) {
        return "The interface " + intName + " is not available.";
    }

    /**
     * Returns the interface create model object data.
     *
     * @param ifNames interfaces
     * @param ifs     interface instance
     * @param id      device id
     * @return interface model object data
     */
    static ModelObjectData getIntCreateModObj(List<String> ifNames,
                                              Interfaces ifs, String id) {
        ModelObjectData modData;
        if (ifNames.size() > 1) {
            modData = buildIntModDataDevice(id, ifs);
        } else {
            modData = buildIntModDataRoot(id, ifs);
        }
        return modData;
    }

    /**
     * Builds the device model interface model object data, with respect to
     * root level.
     *
     * @param id  device id
     * @param ifs interface object
     * @return model object data, with root level
     */
    private static ModelObjectData buildIntModDataRoot(String id,
                                                       Interfaces ifs) {
        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
                .rev20140508.ietfinterfaces.Devices devices =
                new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang
                        .ietf.interfaces.rev20140508.ietfinterfaces
                        .DefaultDevices();
        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
                .rev20140508.ietfinterfaces.devices.Device device =
                new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang
                        .ietf.interfaces.rev20140508.ietfinterfaces.devices
                        .DefaultDevice();
        List<org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
                .interfaces.rev20140508.ietfinterfaces.devices
                .Device> deviceList = new LinkedList<>();

        device.deviceid(id);
        device.interfaces(ifs);
        deviceList.add(device);
        devices.device(deviceList);
        return DefaultModelObjectData.builder()
                .addModelObject((InnerModelObject) devices).build();
    }

    /**
     * Returns the BGP create driver info.
     *
     * @param bgpMap BGP map
     * @param id     device id
     * @param devBgp device BGP info
     * @param intBgp interface BGP info
     * @return BGP driver config
     */
    static BgpDriverInfo getBgpCreateConfigObj(Map<BgpInfo, DeviceId> bgpMap,
                                               String id, BgpInfo devBgp,
                                               BgpInfo intBgp) {
        boolean isDevIdPresent = isDevIdBgpPresent(bgpMap, id);
        BgpDriverInfo info;
        if (devBgp != intBgp) {
            //TODO: With ipv6 BGP it has to be changed
            info = new BgpDriverInfo(VPN, id);
        } else if (isDevIdPresent) {
            info = new BgpDriverInfo(DEVICE, id);
        } else if (bgpMap.size() != 0) {
            info = new BgpDriverInfo(DEVICES, id);
        } else {
            info = new BgpDriverInfo(ROOT, id);
        }
        return info;
    }

    /**
     * Returns true if the device is present in the BGP map; false otherwise.
     *
     * @param bgpMap BGP map
     * @param id     device id
     * @return true if device is present; false otherwise
     */
    private static boolean isDevIdBgpPresent(Map<BgpInfo, DeviceId> bgpMap,
                                             String id) {
        for (Map.Entry<BgpInfo, DeviceId> info : bgpMap.entrySet()) {
            DeviceId devId = info.getValue();
            if (devId.toString().equals(id)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the model object data for VPN instance deletion.
     *
     * @param intMap interface map
     * @param ins    VPN instance
     * @param id     device id
     * @return model object data
     */
    static ModelObjectData getVpnDelModObj(Map<AccessInfo, InterfaceInfo> intMap,
                                           NetworkInstances ins,
                                           String id) {
        boolean isDevIdPresent = isDevIdPresent(intMap, id);
        ModelObjectData modData;
        if (intMap.size() == 0) {
            modData = buildInsModDataRoot(id, ins);
        } else if (isDevIdPresent) {
            modData = buildInsModDataDevice(id, ins);
        } else {
            modData = buildInsModDataDevices(id, ins);
        }
        return modData;
    }

    /**
     * Returns the BGP driver info for VPN BGP instance deletion.
     *
     * @param bgpMap BGP map
     * @param id     device id
     * @return BGP driver info
     */
    static BgpDriverInfo getVpnBgpDelModObj(Map<BgpInfo, DeviceId> bgpMap,
                                            String id) {
        boolean isDevIdPresent = isDevIdBgpPresent(bgpMap, id);
        BgpDriverInfo driInfo;
        if (bgpMap.size() == 0) {
            driInfo = new BgpDriverInfo(ROOT, id);
        } else if (isDevIdPresent) {
            driInfo = new BgpDriverInfo(DEVICE, id);
        } else {
            driInfo = new BgpDriverInfo(DEVICES, id);
        }
        return driInfo;
    }
}
