/*
 * Copyright 2015 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.provider.pcep.tunnel.impl;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.collections.map.MultiKeyMap;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelProviderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Entity to provide tunnel DB and mapping for request/response between CORE to PCEP
 * and PCEP to PCC.
 */
public class PcepTunnelApiMapper {
    protected static final Logger log = LoggerFactory.getLogger(PcepTunnelApiMapper.class);

    static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
    // Map to store all the tunnel requests.
    private Map<Integer, PcepTunnelData> tunnelRequestQueue;
    //Map to store all core related tunnel requests.
    private Map<TunnelId, PcepTunnelData> coreTunnelRequestQueue;
    //Map to store all the created tunnels.
    private Map<Integer, PcepTunnelData> tunnelDB;
    // Map to store the tunnel ids, given by core and given by pcc.
    private Map<TunnelId, Integer> tunnelIdMap;
    //Map to store all the learnt tunnels.
    private MultiKeyMap pccTunnelDB = new MultiKeyMap();

    TunnelProviderService tunnelApiMapperservice;

    /**
     * Default constructor.
     */
    public PcepTunnelApiMapper() {
        //TODO check if the map need to initialize
        tunnelRequestQueue = new HashMap<Integer, PcepTunnelData>();
        coreTunnelRequestQueue = new HashMap<TunnelId, PcepTunnelData>();
        tunnelDB = new HashMap<Integer, PcepTunnelData>();
        tunnelIdMap = new HashMap<TunnelId, Integer>();
    }

    /**
     * Add tunnels to tunnel Request queues.
     *
     * @param srpId srp id
     * @param pcepTunnelData pcep tunnel data
     */
    public void addToTunnelRequestQueue(int srpId, PcepTunnelData pcepTunnelData) {
        tunnelRequestQueue.put(new Integer(srpId), pcepTunnelData);
        log.debug("Tunnel Added to TunnelRequestQueue");
    }

    /**
     * Map between Tunnel ID and pcc provided Tunnel ID.
     *
     * @param pcepTunnelData pcep tunnel data
     */
    public void addToTunnelIdMap(PcepTunnelData pcepTunnelData) {
        int value = pcepTunnelData.statefulIpv4IndentifierTlv().getTunnelId() & 0xFFFF;
        tunnelIdMap.put(pcepTunnelData.tunnel().tunnelId(), (new Integer(value)));
        log.debug("Tunnel ID Added to tunnelIdMap");
    }

    /**
     * Add tunnels to core tunnel request queue.
     *
     * @param pcepTunnelData pcep tunnel data
     */
    public void addToCoreTunnelRequestQueue(PcepTunnelData pcepTunnelData) {
        coreTunnelRequestQueue.put(pcepTunnelData.tunnel().tunnelId(), pcepTunnelData);
        log.debug("Tunnel Added to CoreTunnelRequestQueue");
    }

    /**
     * Removes tunnels from the core tunnel request queue.
     *
     * @param tunnelId tunnel id
     */
    public void removeFromCoreTunnelRequestQueue(TunnelId tunnelId) {
        coreTunnelRequestQueue.remove(tunnelId);
        log.debug("Tunnnel create response sent to core and removed from CoreTunnelRequestQueue");
    }

    /**
     * Handle the report which comes after initiate message.
     *
     * @param srpId srp id
     * @param pcepTunnelData pcep tunnel data
     */
    public void handleCreateTunnelRequestQueue(int srpId, PcepTunnelData pcepTunnelData) {

        int value = tunnelIdMap.get(pcepTunnelData.tunnel().tunnelId());
        tunnelDB.put(new Integer(value), pcepTunnelData);
        tunnelRequestQueue.remove(new Integer(srpId), pcepTunnelData);
        log.debug("Tunnel Added to TunnelDBQueue and removed from TunnelRequestQueue. tunnel id {}"
                + (new Integer(value)).toString());
    }

    /**
     * Handle report which comes for update message.
     *
     * @param srpId srp id
     * @param pcepTunnelData pcep tunnel data
     */
    public void handleUpdateTunnelRequestQueue(int srpId, PcepTunnelData pcepTunnelData) {
        if (pcepTunnelData.rptFlag()) {
            pcepTunnelData.setRptFlag(false);
            int value = tunnelIdMap.get(pcepTunnelData.tunnel().tunnelId());
            tunnelDB.put(new Integer(value), pcepTunnelData);
            tunnelRequestQueue.remove(new Integer(srpId), pcepTunnelData);
            log.debug("Tunnel Added to TunnelDBQueue and removed from TunnelRequestQueue. tunnel id {}",
                      (new Integer(value)).toString());
        } else {
            pcepTunnelData.setRptFlag(true);
            tunnelRequestQueue.put(new Integer(srpId), pcepTunnelData);
            log.debug("Tunnel updated in TunnelRequestQueue");
        }
    }

    /**
     * Handle report for tunnel Release request.
     *
     * @param srpId srp id
     * @param pcepTunnelData pcep tunnel data
     */
    public void handleRemoveFromTunnelRequestQueue(int srpId, PcepTunnelData pcepTunnelData) {

        int value = tunnelIdMap.get(pcepTunnelData.tunnel().tunnelId());
        tunnelIdMap.remove(pcepTunnelData.tunnel().tunnelId());
        tunnelDB.remove(new Integer(value));
        tunnelRequestQueue.remove(srpId);
        log.debug("Tunnel removed from  TunnelDBQueue and TunnelRequestQueue");
    }

    /**
     * Returns PcepTunnelData from the tunnel request queue.
     *
     * @param srpId srp id
     * @return PcepTunnelData pcep tunnel data
     */
    public PcepTunnelData getDataFromTunnelRequestQueue(int srpId) {
        return tunnelRequestQueue.get(new Integer(srpId));

    }

    /**
     * Returns PcepTunnelData from the tunnel DB.
     *
     * @param tunnelId tunnel id
     * @return PcepTunnelData pcep tunnel data
     */
    public PcepTunnelData getDataFromTunnelDBQueue(TunnelId tunnelId) {
        int value = tunnelIdMap.get(tunnelId);
        return tunnelDB.get((new Integer(value)));
    }

    /**
     * Checks whether the tunnel exist in tunnel request queue.
     *
     * @param srpId srp id
     * @return true if tunnel exist in reuest queue, false otherwise
     */
    public boolean checkFromTunnelRequestQueue(int srpId) {
        boolean retValue = tunnelRequestQueue.containsKey(srpId);
        return retValue;
    }

    /**
     * Returns whether tunnel exist in tunnel db.
     *
     * @param tunnelId tunnel id
     * @return true/false if the tunnel exists in the tunnel db
     */
    public boolean checkFromTunnelDBQueue(TunnelId tunnelId) {
        int value = tunnelIdMap.get(tunnelId);
        boolean retValue = tunnelDB.containsKey((new Integer(value)));
        return retValue;
    }

    /**
     * Add Learnt tunnels to pcc tunnel DB.
     *
     * @param pcepTunnelData pcep tunnel data
     */
    public void addPccTunnelDB(PcepTunnelData pcepTunnelData) {
        pccTunnelDB.put(pcepTunnelData.statefulIpv4IndentifierTlv().getTunnelId() & 0xFFFFL,
                        pcepTunnelData.statefulIpv4IndentifierTlv().getIpv4IngressAddress(), pcepTunnelData);
    }
}
