/**
   * Runs a test application that allocates streams, generates an SDP, dumps it on stdout, waits for
   * a remote peer SDP on stdin, then feeds that to our local agent and starts ICE processing.
   *
   * @param args none currently handled
   * @throws Throwable every now and then.
   */
  public static void main(String[] args) throws Throwable {
    final Agent localAgent = createAgent(2020);
    localAgent.setNominationStrategy(NominationStrategy.NOMINATE_HIGHEST_PRIO);

    //        localAgent.addStateChangeListener(new IceProcessingListener());

    // let them fight ... fights forge character.
    localAgent.setControlling(false);
    String localSDP = SdpUtils.createSDPDescription(localAgent);

    // wait a bit so that the logger can stop dumping stuff:
    Thread.sleep(500);

    System.out.println(
        "=================== feed the following" + " to the remote agent ===================");

    System.out.println(localSDP);

    System.out.println(
        "======================================" + "========================================\n");

    String sdp = readSDP();

    startTime = System.currentTimeMillis();
    SdpUtils.parseSDP(localAgent, sdp);

    localAgent.startConnectivityEstablishment();

    localAgent.addStateChangeListener(
        new PropertyChangeListener() {
          @Override
          public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
            if (propertyChangeEvent.getPropertyName().equals(Agent.PROPERTY_ICE_PROCESSING_STATE)
                && propertyChangeEvent.getNewValue().equals(IceProcessingState.COMPLETED)) {
              System.out.println("************************!!!!!!!!!!!!!  Start doing stuff here");
              IceMediaStream stream = localAgent.getStream("video");
              CandidatePair rtpPair = stream.getComponent(Component.RTP).getSelectedPair();
              CandidatePair rtcpPair = stream.getComponent(Component.RTCP).getSelectedPair();

              DatagramSocket rtpSocket = rtpPair.getLocalCandidate().getDatagramSocket();
              DatagramSocket rtcpSocket = rtcpPair.getLocalCandidate().getDatagramSocket();
              byte[] data = "sent".getBytes();
              RemoteCandidate rem = rtpPair.getRemoteCandidate();
              TransportAddress target = rem.getHostAddress();
              DatagramPacket p =
                  new DatagramPacket(data, data.length, target.getAddress(), target.getPort());
              try {
                System.out.println("About to send packet..");
                rtpSocket.send(p);
                System.out.println("Receiving packet..");
                DatagramPacket p2 = new DatagramPacket(new byte[data.length], data.length);
                rtpSocket.receive(p2);
                System.out.println("========Received: " + new String(p2.getData()));
              } catch (IOException e) {
                e.printStackTrace();
              }
            }
          }
        });
    // Give processing enough time to finish. We'll System.exit() anyway
    // as soon as localAgent enters a final state.
    Thread.sleep(60000);
  }