/*
 * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * The contents of this file are subject to the Sun Community Source License,
 * Jini Software Kit, v. 1.0 DC (the "License"); you may not use this
 * file except in compliance with the License.  You may obtain a copy of
 * the License at http://java.sun.com/products/jini. Software distributed
 * under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY
 * OF ANY KIND, either express or implied.  See the License for the
 * specific language governing rights and limitations under the License.
 * 
 * CopyrightVersion 1.0_JiniDC_Public
 */
package mde.jini.service;

import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.activation.*;
import java.rmi.server.*;
import java.util.*;
import net.jini.discovery.*;
import net.jini.core.lookup.*;

/**
 * This class is a server which accepts socket connections from the PalmPilot, creating
 * a PalmProxy instance for each new connection.
 */
public class PalmDaemonImpl extends Thread implements PalmDaemon, DiscoveryListener {
   
   private Map registrars = Collections.synchronizedMap(new HashMap());
   private String[] groups;
   private ServerSocket server;
   private LookupDiscovery discovery;

   /** Create a new palm daemon server */
   public PalmDaemonImpl(ActivationID id, MarshalledObject data) throws RemoteException {
      Activatable.exportObject(this, id, 0);
      try {
         groups = (String[])data.get();
      } catch (Exception e) {
         e.printStackTrace();
      }      
   }

   /** Start a server process which accepts connections on the given port */
   public void startup(int port) throws RemoteException {
      try {
         server = new ServerSocket(port);
         discovery = new LookupDiscovery(groups);
      } catch (IOException e) {
         e.printStackTrace();
      }
      System.out.println("PalmDaemonImpl: listening for connections on port " + port);
      discovery.addDiscoveryListener(this);
      start();
   }

   /** Start a server thread for handling connections */
   public void run() {
      try {
         while (true) {
            new PalmProxy(server.accept(), getLookupServers()).start();
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   /** DiscoveryListener interface method */
   public void discovered(DiscoveryEvent event) {
      System.out.println("PalmDaemon.discovered(): Jini lookup server discovered...");
      synchronized (registrars) {
         ServiceRegistrar[] regs = event.getRegistrars();
         for (int i = 0; i < regs.length; i++) {
            registrars.put(regs[i].getServiceID(), regs[i]);
         }
      }
   }

   /** DiscoveryListener interface method */
   public void discarded(DiscoveryEvent event) {
      System.out.println("PalmDaemon.discovered(): Jini lookup server discarded...");
      synchronized (registrars) {
         ServiceRegistrar[] regs = event.getRegistrars();
         for (int i = 0; i < regs.length; i++) {
            registrars.remove(regs[i].getServiceID());
         }
      }
   }

   private ServiceRegistrar[] getLookupServers() {
      synchronized (registrars) {
         return (ServiceRegistrar[])registrars.values().toArray(new ServiceRegistrar[0]);
      }
   }
   
}