package brn.sim.handler;

import click.runtime.ClickException;
import click.swans.net.ClickRouter;
import jist.swans.misc.Event;
import brn.sim.DataManager;
import brn.sim.DataManager.DataContributor;
import brn.sim.data.DiagramData;

public class StatsClickHandler extends DataContributor {

  public class NodeData {
    protected int id;
    private String category;

    protected DiagramData queueLength = null;

    public NodeData(int id) {
      this.id = id;
      this.category = getCategory(id);
    }

    public String getCategory(int id) {
      return "Node " + Integer.toString(id);
    }

    public String getCategory() {
      return category;
    }

    protected DiagramData getQueueLength() {
      // Mac Discard counter
      if (null == queueLength) {
        queueLength = new DiagramData(
            new String[] {category, "Net", "queue length"}, "time", "s",
                "queue length", "n/a");
        addData(queueLength, DataManager.LEVEL_BASIC);
      }

      return queueLength;
    }
  }

  private static final String ID = "ClickHandler";
  private double sampleLen;
  private NodeData[] nodeData;

  public StatsClickHandler(double sampleLen) {
    this.sampleLen = sampleLen;
    this.nodeData = new NodeData[20];
  }

  protected NodeData getNodeData(int id) {
    try {
      if (null == nodeData[id])
        nodeData[id] = new NodeData(id);
    }
    catch (ArrayIndexOutOfBoundsException e) {
      if (id > 50000)
        throw new RuntimeException("id to large");
      NodeData[] tmp = new NodeData[id + 100];
      System.arraycopy(nodeData, 0, tmp, 0, nodeData.length);
      nodeData = tmp;
      return getNodeData(id);
    }
    return nodeData[id];
  }

  /*
   * (non-Javadoc)
   * @see brn.sim.DataManager.DataContributor#getId()
   */
  public String getId() {
    return ID;
  }

  /*
   * (non-Javadoc)
   * @see brn.sim.DataManager.DataContributor#registerHandlers()
   */
  public void registerHandlers() {
    super.registerHandlers();

    Event.addHandler(ClickRouter.ClickPullEvent.class, new Event.Handler() {
      public void handle(Event event) {
        ClickRouter.ClickPullEvent ev = (ClickRouter.ClickPullEvent) event;
        String length = null;
        try {
          length = ev.getRouter().readHandler("meshNode/be_q/queue", "length");
        } catch (ClickException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          return;
        }

        int l = Integer.parseInt(length);
        getNodeData(ev.nodeId).getQueueLength().addNextTimePoint(ev.time, l);
      }
    });

    Event.addHandler(ClickRouter.ClickPullEvent.class, new ClickRouteTracer());
    // TODO place your handlers here!
  }

}
