package org.etsi.its.adapter.layers;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

import org.etsi.common.ByteHelper;
import org.etsi.its.adapter.IManagementLayers;
import org.etsi.its.adapter.UdpMultiplexer;

public class UdpIpMarbenLayer extends UdpIpLayer {

    // Marben 88:ceres  182:Jupiter VM32G
    private static String UdpAddress = "192.168.7.182"; //"10.200.1.101"; // FIXME Use a generic way to retrieve UDP settings
    
    private static int UdpRecvPort = 3751; //18501; // FIXME Use a generic way to retrieve UDP settings
    
    private static int UdpSendPort = 3750; //18502; // FIXME Use a generic way to retrieve UDP settings
    
    private Map<String, Short> clientsToFrameTypes = new HashMap<String, Short>();
    
    public UdpIpMarbenLayer(IManagementLayers management, Stack<String> lowerStack) {
        super(management, lowerStack);
        UdpMultiplexer.getInstance().UdpAddress = UdpAddress;
        UdpMultiplexer.getInstance().UdpRecvPort = UdpRecvPort;
        UdpMultiplexer.getInstance().UdpSendPort = UdpSendPort;
    }
    
    /* (non-Javadoc)
     * @see org.etsi.its.adapter.layers.Layer#register(org.etsi.its.adapter.layers.Layer)
     */
    @Override
    public void register(Layer upperLayer) {
        if(registeredUpperLayer == null) {
            super.register(upperLayer);
            // Workaround for Marben CAM send module
            Map<String, Object> lowerInfo = new HashMap<String, Object>();
            lowerInfo.put(UdpMultiplexer.getInstance().UDP_PORT_KEY, new Integer(UdpRecvPort).toString()); 
            super.send(new byte[] { (byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA }, lowerInfo);
        } else {
            super.register(upperLayer);
        }
        clientsToFrameTypes.put(this.toString(), upperLayerFrameType);
    }
    
    /* (non-Javadoc)
     * @see org.etsi.its.adapter.layers.Layer#unregister(org.etsi.its.adapter.layers.Layer)
     */
    @Override
    public void unregister(Layer upperLayer) {
        super.unregister(upperLayer);
        clientsToFrameTypes.remove(this.toString(), upperLayerFrameType);
    }
    
    /* (non-Javadoc)
     * @see org.etsi.its.adapter.layers.Layer#send(byte[], java.util.Map)
     */
    @Override
    public boolean send(byte[] message, Map<String, Object> params) {
        System.out.println("UdpIpMarbenLayer.send: " + ByteHelper.byteArrayToString(message));
        
        return super.send(message, params); // ML(Marben) : no lower header added 
    }
    
    public void receive(byte[] message, Map<String, Object> lowerInfo) {
        
        System.out.println("UdpIpMarbenLayer.run: Received packet " + ByteHelper.byteArrayToString(message));

        lowerInfo.put(EthernetLayer.LINK_LAYER_DESTINATION, MAC_BROADCAST);
        
        registeredUpperLayer.receive(message, lowerInfo); // no MAC+LLC headers expected for Marben (ML) 
    }
    
}
