import java.net.*;
import java.util.*;
import java.io.*;


public class FakeBridge extends Bridge implements Runnable {
  static String host;
  
  public static void main(String args[]){
    (new FakeBridge(true)).init(args[0]);
  }

  public void init(String h){
    host = h;
    System.out.println("Starting FakeBridge with Distributor host of "+h);
    new Thread(new FakeBridge(false)).start();
    new Thread(new FakeBridge(true)).start();
  }

  FakeBridge(boolean type){
    super(type);
  }

  public void run() {
    Random rand;
    DatagramSocket dist;
    byte packetData[] = new byte [TSConstants.MAX_DATA_SIZE];
    byte packetData2[] = new byte [TSConstants.MAX_DATA_SIZE];
    DatagramPacket packet=new DatagramPacket(packetData, TSConstants.MAX_DATA_SIZE);
    Vector queue = new Vector();
    int ct, ct2, i, re;
    InetAddress hipaddr;

    if(listener)
      {
	System.out.println("Starting listener mode.");
	// Open the socket to the distributor
	try { dist = new DatagramSocket(TSConstants.AM_PORT); }
	catch(SocketException e) { System.out.println("Uh oh!"); return; }
	rand = new Random();

	while(true){
	  // Receive the packet
	  try { dist.receive(packet); }
	  catch (IOException e) { continue; }

	  // Which kind of packet is it?
	  // If it is of the right type, fake a response
	  packetData = packet.getData();
	  switch(packetData[4]){
	  case TSConstants.AMULET_QUERY:
	    // Generate bogus reply

	    // Amulet Address
	    for(ct=0;ct<4;ct++){
	      packetData2[ct] = packetData[ct];
	    }
	    // Message type
	    packetData2[4] = TSConstants.AMULET_STATE;

	    // Random IR ID
	    for(ct=5; ct<9 ; ct++){
	      packetData2[ct] = (byte) (rand.nextInt()%256);
	    } 
	    // Random byte of button info
	    packetData2[9] = (byte) (rand.nextInt()%2);
	    // Random byte of led info
	    packetData2[10] = (byte) (rand.nextInt()%256);
	    // Random byte of streaming states
	    packetData2[11] = (byte) (rand.nextInt()%2);
	    // Reason
	    packetData2[12] = TSConstants.QUERY_REPLY;

	    // Queue delayed response
	    queue.addElement(new DatagramPacket(packetData2, 13, 
						packet.getAddress(), 
						TSConstants.DIST_PORT));
	    break;
	  case TSConstants.ROUTE_QUERY:
	    // Generate bogus reply

	    // Amulet Address
	    for(ct=0;ct<4;ct++){
	      packetData2[ct] = packetData[ct];
	    }
	    // Message type
	    packetData2[4] = TSConstants.ROUTE_STATE;

	    i = rand.nextInt()%12;
	    packetData2[5] = (byte) i;
	    packetData2[6] = packetData2[7] = packetData2[8] = 0;
	    for(ct=0; ct< i*4; ct++){
	      packetData2[9+ct] = (byte) (rand.nextInt()%256);
	    }
	    // Queue delayed response
	    queue.addElement(new DatagramPacket(packetData2, 9+(i*4), 
						packet.getAddress(), 
						TSConstants.DIST_PORT));
	    break;
	  case TSConstants.CHIRP:
	    break;
	  case TSConstants.PLAY_AUDIO:
	    break;
	  case TSConstants.SET_LED_STATE:
	    break;
	  case TSConstants.SET_AUDIO_STREAMING:
	    break;
	  }
	  
	}
      }

    else

      {
	System.out.println("Starting talker mode.");
	try { 
	  dist = new DatagramSocket(TSConstants.DIST_PORT);
	  hipaddr = InetAddress.getByName(host);
	}
	catch(Exception e) { System.out.println("Uh oh(dist)! "+e); return; }
	rand = new Random();

	while(true){
	  // Don't process the queue faster than is realistic
	  try {Thread.sleep(100);} catch (Exception e) {}

	  // Are there any queued fake responses to send?
	  if(queue.size() >= 1){
	    System.out.println("Packets in the queue! "+queue.size());
	    // Assure a minimum delay
	    try { Thread.sleep(30); } catch (Exception e) {}

	    // Pop the packet off the queue
	    packet = (DatagramPacket) queue.firstElement();
	    queue.removeElementAt(0);
	    
	    // And off it goes!
	    try { 	
	      System.out.println("Inetaddress of "+host+" is "+InetAddress.getByName(host));
	    dist.send(packet); }
	    catch (IOException e) { }
	  }
	  
	  // Maybe we should generate some spontaneous events?
	  if((re = (rand.nextInt()%256)) < 4){
	    int why;
	    // Spontaneous wakeup
	    System.out.println("Sending spontaneous event");
	    // Generate bogus reply
	    
	    // Amulet Address
	    for(ct=0;ct<4;ct++){
	      packetData2[ct] = (byte) (rand.nextInt()%256);
	    }
	    // Message type
	    packetData2[4] = TSConstants.AMULET_STATE;
	    
	    // Random IR ID
	    for(ct=5; ct<9 ; ct++){
	      packetData2[ct] = (byte) (rand.nextInt()%256);
	    } 
	    // Random byte of button info
	    packetData2[9] = (byte) (rand.nextInt()%2);
	    // Random byte of led info
	    packetData2[10] = (byte) (rand.nextInt()%256);
	    // Random byte of streaming states
	    packetData2[11] = (byte) (rand.nextInt()%2);
	    // Reason
	    why = rand.nextInt()%3;
	    if(why == 0)
	      packetData2[12] = TSConstants.QUERY_REPLY;
	    if(why == 1)
	      packetData2[12] = TSConstants.BUTTON_CHANGED;
	    if(why == 2)
	      packetData2[12] = TSConstants.IR_SEEN;
	    
	    // Queue delayed response
	    queue.addElement(new DatagramPacket(packetData2, 13, 
						hipaddr, 
						  TSConstants.DIST_PORT));
	      
	  }

	}
      }
  }
}
