package test.click;

import jist.swans.Constants;
import jist.swans.Node;
import jist.swans.misc.Message;
import jist.swans.misc.MessageBytes;
import jist.swans.net.NetAddress;
import jist.swans.trans.TransUdp;
import brn.sim.AbstractDriver;
import brn.sim.AbstractParams;
import brn.sim.DataManager;
import brn.sim.builder.AppBuilder;
import brn.sim.builder.Builder;
import brn.sim.builder.BuilderException;
import brn.sim.builder.FlowBuilder;
import brn.sim.builder.NodeBuilder;
import brn.sim.builder.FlowBuilder.CbrUdpParams;
import brn.sim.builder.NodeBuilder.NodeParams;
import brn.sim.builder.NodeBuilder.FlowParams;
import brn.sim.builder.TransBuilder.UdpParams;
import brn.sim.data.dump.WiresharkDump;
import click.sim.builder.ClickBuilder;
import click.sim.builder.ClickBuilder.NetRemoteParams;
import click.sim.builder.ClickBuilder.NetRemote;
import click.swans.net.ClickRemoteRouter;

public class RemoteTest extends AbstractDriver {

  /**
   * @param args
   * @throws BuilderException
   */
  public static void main(String[] args) throws Exception {
//    testDump();
//    testBrnLocalLoop();
//    testBrnRemoteLoop();
    testWrapRemoteLoop();
  }

  public static void test1() throws BuilderException {
    NetRemoteParams params = new NetRemoteParams();

    params.hosts = new String[] {"192.168.3.63"};
    params.startupScript = null;
    params.shutdownScript = null;
    params.clickScript = "res/click/RemoteClickTest.click";

    NetRemote builder = new NetRemote();
    Node node = new Node(1);
    Object obj = builder.build(params, node);

    builder.hookUp(params, node, obj);

    ClickRemoteRouter router = (ClickRemoteRouter) obj;

    Message msg = new TransUdp.UdpMessage(23,24,new MessageBytes("bla"));
    router.send(msg, new NetAddress(1), Constants.NET_PROTOCOL_UDP,
        (byte)0, (byte)64, null);
  }

  public static void testWrapRemoteLoop() throws Exception {
    FlowBuilder.CbrUdpParams flowParams = new FlowBuilder.CbrUdpParams();
    flowParams.flowId = 1;
    flowParams.clientAddr = new NetAddress(1);
    flowParams.clientPort = 9999;
    flowParams.start = 50000;
    flowParams.end = 70000;
    flowParams.poissonArrival = true;
    flowParams.serverAddr = new NetAddress(2);
    flowParams.serverPort = 9999;
    flowParams.udpTxRate = 150;
    FlowBuilder.CbrUdpParams pingParams = (CbrUdpParams) flowParams.clone();
    pingParams.flowId = 0;
    pingParams.udpTxRate = 4;
    pingParams.start = flowParams.start - 4000;
    pingParams.end = flowParams.start - 1000;

    ClickBuilder.NetRemoteParams netParams = new ClickBuilder.NetRemoteParams();
    netParams.hosts = new String[]{"192.168.3.218", "192.168.3.234"};
    netParams.clickScript = "res/click/r_main.click";
    netParams.dumpFilePrefix = "dump-node-";
    netParams.startupScript = "res/click/startup-wrap.sh";
    netParams.shutdownScript = "res/click/shutdown.sh";
    netParams.pullRemotePackets = true;
    netParams.processRemotePackets = true;
    netParams.collectRemotePacketsAtEnd = false;
    netParams.clickPacketEncap = WiresharkDump.FAKE_DLT_EN10MB;
    netParams.connectorProperties = ClickBuilder.CONNECTOR_WRAP;

    FlowParams nodeParams = new FlowParams();
    nodeParams.radio = null;
    nodeParams.mac = null;
    nodeParams.net = netParams;
    nodeParams.route = null;
    nodeParams.trans = new UdpParams();
    nodeParams.flows = new Builder.Params[] {pingParams, flowParams};

    AbstractParams params = new AbstractParams();
    params.nodeNumber = new int[] {2};
    params.nodeParams = new NodeBuilder.NodeParams[] {nodeParams};
    params.endTime = 75;

    params.handlerTransLevel = DataManager.LEVEL_ALL;
    params.handlerFlowLevel = DataManager.LEVEL_ALL;
    params.handlerNetLevel = DataManager.LEVEL_ALL;

    params.db = true;

    RemoteTest test = new RemoteTest();
    test.run(params);
  }

  public static void testWrapLocalLoop() throws Exception {
    AppBuilder.UdpParams clientParams = new AppBuilder.UdpParams();
    clientParams.client = true;
    clientParams.clientAddr = new NetAddress(1);
    clientParams.serverAddr = new NetAddress(1);
    clientParams.clientPort = 250;
    clientParams.start = 10000;
    clientParams.end = 20000;
    clientParams.poissonArrival = true;
    clientParams.serverPort = 24;
    clientParams.udpTxRate = 10;

    ClickBuilder.NetRemoteParams netParams = new ClickBuilder.NetRemoteParams();
    netParams.hosts = new String[] {"192.168.3.63"};
    netParams.startupScript = null;
    netParams.shutdownScript = null;
    netParams.clickScript = "res/click/r_localloop.click";
    netParams.dumpFilePrefix = "dump-node-";
    netParams.pullRemotePackets = true;
    netParams.collectRemotePacketsAtEnd = false;
    netParams.clickPacketEncap = WiresharkDump.FAKE_DLT_EN10MB;

    FlowParams nodeParams = new FlowParams();
    nodeParams.radio = null;
    nodeParams.mac = null;
    nodeParams.net = netParams;
    nodeParams.route = null;
    nodeParams.trans = new UdpParams();
    nodeParams.flows = new Builder.Params[] {clientParams};

    AbstractParams params = new AbstractParams();
    params.nodeNumber = new int[] {2};
    params.nodeParams = new NodeBuilder.NodeParams[] {nodeParams};
    params.endTime = 20;

    params.handlerTransLevel = DataManager.LEVEL_ALL;
    params.handlerFlowLevel = DataManager.LEVEL_ALL;
    params.handlerNetLevel = DataManager.LEVEL_ALL;

    RemoteTest test = new RemoteTest();
    test.run(params);
  }

  public static void testDump() throws Exception {
    ClickBuilder.NetRemoteParams netParams = new ClickBuilder.NetRemoteParams();
    netParams.hosts = new String[]{"192.168.3.218"} ;//;{"192.168.3.81"};
//    netParams.startupScript = "ifconfig wlan0 down"
//      + "\n iwconfig wlan0 mode monitor channel 1"
//      + "\n ifconfig wlan0 up"
//      + "\n killall click"
//      + "\n cd /home/kurth/projects/click-mips/click-core/userlevel/"
//      + "\n ./click --allow-reconfigure " +
//          "-e \"_simDeviceMaster :: SimDeviceMaster(TCP, 7777)\" > /home/kurth/out.txt 2>&1 &"
//      + "\n sleep 2";
//    netParams.shutdownScript = "ifconfig wlan0 down\n";
//    netParams.startupScript = null;
//    netParams.shutdownScript = null;
    netParams.clickScript = "res/click/r_dump.click";
//    netParams.clickScript = "res/click/RemoteClickTest.click";
    netParams.dumpFilePrefix = "dump-node-";
    netParams.pullRemotePackets = true;
    netParams.processRemotePackets = false;
    netParams.collectRemotePacketsAtEnd = false;
    netParams.clickPacketEncap = WiresharkDump.FAKE_DLT_PRISM_HEADER;
//    netParams.connector = "click.runtime.remote.WrapSshConnector2";
    netParams.connectorProperties = "class=click.runtime.remote.WrapSshConnector2"
      + "\n port=22"
      + "\n user=root"
      + "\n prompt=root@OpenWrt"
      + "\n keyfile=~/.ssh./id_rsa";

    NodeParams nodeParams = new NodeParams();
    nodeParams.radio = null;
    nodeParams.mac = null;
    nodeParams.net = netParams;
    nodeParams.route = null;

    AbstractParams params = new AbstractParams();
    params.nodeNumber = new int[] {1};
    params.nodeParams = new NodeBuilder.NodeParams[] {nodeParams};
    params.endTime = 20;

    params.handlerNetLevel = DataManager.LEVEL_ALL;

    RemoteTest test = new RemoteTest();
    test.run(params);
  }

  public static void testBrnLocalLoop() throws Exception {
    AppBuilder.UdpParams clientParams = new AppBuilder.UdpParams();
    clientParams.client = true;
    clientParams.clientAddr = new NetAddress(1);
    clientParams.serverAddr = new NetAddress(1);
    clientParams.clientPort = 250;
    clientParams.start = 60000;
    clientParams.end = 70000;
    clientParams.poissonArrival = true;
    clientParams.serverPort = 24;
    clientParams.udpTxRate = 200;
    AppBuilder.UdpParams serverParams = (AppBuilder.UdpParams) clientParams.clone();
    serverParams.client = false;

    ClickBuilder.NetRemoteParams netParams = new ClickBuilder.NetRemoteParams();
    netParams.hosts = new String[]{"192.168.3.218"};
    netParams.clickScript = "res/click/r_main.click";
//    netParams.startupScript = null;
//    netParams.shutdownScript = null;
    netParams.dumpFilePrefix = "dump-node-";
    netParams.pullRemotePackets = true;
    netParams.processRemotePackets = true;
    netParams.collectRemotePacketsAtEnd = false;
    netParams.clickPacketEncap = WiresharkDump.FAKE_DLT_EN10MB;
    netParams.connectorProperties = "class=click.runtime.remote.WrapSshConnector2"
      + "\n port=22"
      + "\n user=root"
      + "\n prompt=root@OpenWrt"
      + "\n keyfile=~/.ssh./id_rsa";

    FlowParams nodeParams = new FlowParams();
    nodeParams.radio = null;
    nodeParams.mac = null;
    nodeParams.net = netParams;
    nodeParams.route = null;
    nodeParams.flows = new Builder.Params[] {clientParams, serverParams};

    AbstractParams params = new AbstractParams();
    params.nodeNumber = new int[] {1};
    params.nodeParams = new NodeBuilder.NodeParams[] {nodeParams};
    params.endTime = 75;

    params.handlerTransLevel = DataManager.LEVEL_ALL;
    params.handlerFlowLevel = DataManager.LEVEL_ALL;
    params.handlerNetLevel = DataManager.LEVEL_ALL;

    params.db = true;

    RemoteTest test = new RemoteTest();
    test.run(params);
  }

  public static void testBrnRemoteLoop() throws Exception {
    FlowBuilder.CbrUdpParams flowParams = new FlowBuilder.CbrUdpParams();
    flowParams.flowId = 1;
    flowParams.clientAddr = new NetAddress(1);
    flowParams.clientPort = 9999;
    flowParams.start = 50000;
    flowParams.end = 70000;
    flowParams.poissonArrival = true;
    flowParams.serverAddr = new NetAddress(2);
    flowParams.serverPort = 9999;
    flowParams.udpTxRate = 50;
    FlowBuilder.CbrUdpParams pingParams = (CbrUdpParams) flowParams.clone();
    pingParams.flowId = 0;
    pingParams.udpTxRate = 4;
    pingParams.start = flowParams.start - 4000;
    pingParams.end = flowParams.start - 1000;

    ClickBuilder.NetRemoteParams netParams = new ClickBuilder.NetRemoteParams();
    netParams.hosts = new String[]{"192.168.3.63", "192.168.3.81"};
    netParams.clickScript = "res/click/r_main_aligned.click";
    netParams.dumpFilePrefix = "dump-node-";
    netParams.pullRemotePackets = true;
    netParams.processRemotePackets = true;
    netParams.collectRemotePacketsAtEnd = false;
    netParams.clickPacketEncap = WiresharkDump.FAKE_DLT_EN10MB;
    netParams.connectorProperties = ClickBuilder.CONNECTOR_WGT;

    FlowParams nodeParams = new FlowParams();
    nodeParams.radio = null;
    nodeParams.mac = null;
    nodeParams.net = netParams;
    nodeParams.route = null;
    nodeParams.flows = new Builder.Params[] {pingParams, flowParams};

    AbstractParams params = new AbstractParams();
    params.nodeNumber = new int[] {2};
    params.nodeParams = new NodeBuilder.NodeParams[] {nodeParams};
    params.endTime = 75;

    params.handlerTransLevel = DataManager.LEVEL_ALL;
    params.handlerFlowLevel = DataManager.LEVEL_ALL;
    params.handlerNetLevel = DataManager.LEVEL_ALL;

    params.db = true;

    RemoteTest test = new RemoteTest();
    test.run(params);
  }
}
