package profilesj2me;

import java.io.*;
import javax.microedition.io.*;
import javax.bluetooth.*;
import java.util.Vector;
import profiles.*;

class J2MEBasicServiceServer
    extends Thread {
  boolean keepListening = true;
  J2MEBasicService basicService = null;

  J2MEBasicServiceServer(J2MEBasicService bs) {
    basicService = bs;
  }

  /**
   * Termina l'ascolto. Se una connessione è
   * già attiva, smette appena terminato.
   */
  public void stopListening() {
    keepListening = false;
  }

  public boolean isListening() {
    return keepListening;
  }

  public void run() {

    L2CAPConnectionNotifier server = null;
    String message = "";
    byte[] data = null;
    int length;

    try {
      LocalDevice local = LocalDevice.getLocalDevice();
      local.setDiscoverable(DiscoveryAgent.GIAC);
    }
    catch (BluetoothStateException e) {
      System.err.println("Failed to start service");
      System.err.println("BluetoothStateException: " + e.getMessage());
      return;
    }

    try {
      server = (L2CAPConnectionNotifier) Connector.open(
          "btl2cap://localhost:" +
          J2MEBasicService.SERVICE_UUID
          + ";name=Profiles");
    }
    catch (IOException e) {
      System.err.println("Failed to start service");
      System.err.println("IOException: " + e.getMessage());
      return;
    }

    while (keepListening) {

      message = "";
      L2CAPConnection conn = null;

      try {
        conn = server.acceptAndOpen();

        length = conn.getReceiveMTU();
        data = new byte[length];

        length = conn.receive(data);

        while (length != -1) {
          message += new String(data, 0, length);

          try {
            length = conn.receive(data);
          }
          catch (IOException e) {
            break;
          }
        }
        conn.close();

        TextMessage theMessage = TextMessage.fromString(message);

        switch (theMessage.getType()) {
          case profiles.Message.RT_REQ:

            // Trova l'indirizzo del destinatario
            String src = theMessage.getSrcDevice();
            Vector devs = basicService.getDevicesInRange(null);
            int pos = -1;
            for (int i = 0; i < devs.size(); i++) {
              if ( ( (J2MEDevice) devs.elementAt(i)).getURL().startsWith(src,
                  10)) {
                pos = i;
                break;
              }
            }

            System.out.println("Ho ricevuto una richiesta RT:" +
                               " provvedo a inviare la mia tabella a " +
                               src);

            // Rispondi con la tabella di routing
            J2MEDevice thisDevice = (J2MEDevice) basicService.
                getRegisteredListenerDevice();
            TextMessage reply =
                new TextMessage(thisDevice.toString(),
                                thisDevice.getId(),
                                profiles.Message.RT_SND);
            Vector route = new Vector();
            route.addElement(src);
            reply.setRoute(route);

            basicService.deliverMessage(reply);

            System.out.println("Messaggio con RT inviato.");

            break;

          case profiles.Message.RT_SND:
            J2MEDevice updatedDevice =
                J2MEDevice.fromString( (String) theMessage.getMessage());

            System.out.println("Ricevuta RT con : " + updatedDevice);

            // Rimpallala a discoverer
            basicService.getJ2MEBasicServiceDiscoverer().
                rtReceived(updatedDevice);

            break;

          case profiles.Message.BCAST:
            System.out.println("Ricevuto BCAST: " + theMessage);
            basicService.getRegisteredListenerDevice().receive(theMessage);
            basicService.bcast(basicService.getRegisteredListenerDevice(),
                               theMessage);
            break;

          case profiles.Message.USR_MSG:
            System.out.println("Ricevuto USR_MSG: " + theMessage);
            basicService.getRegisteredListenerDevice().receive(theMessage);
            break;

          default:
            System.out.println("Unknown message type!");
            break;
        }

      }
      catch (IOException e) {
        System.out.println("IOException: " + e.getMessage());
      }
      finally {
        if (conn != null) {
          try {
            conn.close();
          }
          catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
    }

    try {
      server.close();
    }
    catch (IOException e) {
      e.printStackTrace();
    }

    System.out.println("server exit");
  }

}