/**
 * 
 */
package org.etsi.its.pcapdump;

import java.io.File;
import java.io.IOException;
import java.net.DatagramPacket;
import java.util.Date;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.etsi.common.ByteHelper;
import org.etsi.its.pcapdump.CmdLineParser.IllegalOptionValueException;
import org.etsi.its.pcapdump.CmdLineParser.UnknownOptionException;

/**
 * @author yann
 *
 */
public class pcapdump implements ILayer {
    
    /**
     * Module version
     */
    public static final String Version = "1.0.0.0";
    
    /**
     * Logger instance
     */
    private final static Logger _logger = Logger.getLogger("org.etsi.its.pcapdump");
    
    private static String NicAddr = "00FF6BADBFC2";
    
    private static String FileName = "itsdump.pcapng";
    
    /**
     * Debug mode. Default: false
     */
    private static Level Debug = Level.OFF;
    
    /**
     * ITS Ehter type
     */
    private static short FrameType = (short) 0x8947;
    
    /**
     * Default ctor
     */
    public pcapdump() {
        // Nothing to do
    }
    
    @Override
    public void dispose() {
        PcapMultiplexer.getInstance().unregister(this);
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        // Process command line arguments
        processCommandLine(args);
        
        // Set traces
        _logger.addHandler(new ConsoleHandler());
        _logger.setLevel(Debug);
        
        
        // Check if the file exist, never remove or scratch files
        File file = new File(FileName);
        if (file.exists()) {
            File newFile = new File(FileName.replace(".", String.format("_%d.", System.currentTimeMillis())));
        	file.renameTo(newFile);
        }
        
        ILayer layer = new pcapdump();
        PcapMultiplexer.getInstance(NicAddr);
        PcapMultiplexer.getInstance().register(layer, FrameType);
        
        boolean bContinue = true;
        while (bContinue) {
            try {
                // Check keyboard
                if (System.in.available() > 0) {
                    int token = System.in.read();
                    switch (token) {
                        case 'h': // Help
                            // No break;
                        case '?': // Help
                            cmdeLineUsage();
                            break;
                        case 'q':
                            bContinue = false;
                            _logger.info("Terminate application...");
                            break;
                    } // End of 'switch' statement
                }
                // Wait
                java.lang.Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } // End of 'while' statement
        
        layer.dispose();
        System.err.println("Terminated");
        System.exit(0);
    }
    
    /**
     * Parse the command line and set options
     * @param args Command line arguments
     */
    private static void processCommandLine(String[] args) {
        // Sanity checks
        if (args.length == 0) {
            return;
        }
        
        CmdLineParser parser = new CmdLineParser();
        CmdLineParser.Option debug = parser.addBooleanOption("Debug");
        CmdLineParser.Option fileName = parser.addStringOption("FileName");
        CmdLineParser.Option frameType = parser.addStringOption("FrameType");
        CmdLineParser.Option NICAddr = parser.addStringOption("NicAddr");
        try {
            parser.parse(args);
        } catch (IllegalOptionValueException e) {
            e.printStackTrace();
            printUsage();
            System.exit(2);
        } catch (UnknownOptionException e) {
            e.printStackTrace();
            printUsage();
            System.exit(3);
        }
        
        Object value;
        if ((value = parser.getOptionValue(debug, false)) != null) {
            Debug = (((Boolean)value).booleanValue() == true) ? Level.ALL : Level.OFF;
        }
        if ((value = parser.getOptionValue(fileName, "")) != null) {
            if (!((String)value).isEmpty()) {
                FileName = (String)value;
            }
        }
        if ((value = parser.getOptionValue(frameType, "")) != null) {
            if (!((String)value).isEmpty()) {
                FrameType = (short)Integer.parseInt((String)value, 16);
            }
        }
        if ((value = parser.getOptionValue(NICAddr, "")) != null) {
            if (!((String)value).isEmpty()) {
                NicAddr = (String)value;
            }
        }
        
    } // End of method processCommandLine
    
    /**
     * Display application usage
     */
    private static void printUsage() {
        System.err.println("Usage: [--Debug (default:false)]\n" +
                " [--FileName=filename \"Output file name \"]\n" + 
                " [--FrameType=0x8947 \"Ethernet prototype\" (0x8947)]\n" + 
                " \n"
        );
    }
    
    private static void cmdeLineUsage() {
        System.err.println("Command Line Usage: \n" + 
                // TODO
                " [q to exit]\n" + 
                " \n"
        );
        
    }
    
	@Override
	public String getFileName() {
		return FileName;
	}
    
}
