/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.shell;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.shell.BrowserChannelServer.SessionHandlerServer;

import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

/**
 * Listens for connections from OOPHM clients.
 */
public class BrowserListener {

  /**
   * Get a query parameter to be added to the URL that specifies the address
   * of this listener.
   * 
   * @param address address of host to use for connections
   * @param port TCP port number to use for connection
   * @return a query parameter
   */
  public static String getDevModeURLParams(String address, int port) {
    return "gwt.codesvr=" + address + ":" + port;
  }

  private ServerSocket listenSocket;

  private Thread listenThread;

  private boolean ignoreRemoteDeath = false;

  /**
   * Listens for new connections from browsers.
   * 
   * @param logger 
   * @param port 
   * @param handler 
   */
  public BrowserListener(final TreeLogger logger, String bindAddress,
      int port, final SessionHandlerServer handler) {
    try {
      listenSocket = new ServerSocket();
      listenSocket.setReuseAddress(true);
      InetAddress address = InetAddress.getByName(bindAddress);
      listenSocket.bind(new InetSocketAddress(address, port));

      if (logger.isLoggable(TreeLogger.TRACE)) {
        logger.log(TreeLogger.TRACE, "Started code server on port "
            + listenSocket.getLocalPort(), null);
      }
      listenThread = new Thread() {
        @Override
        public void run() {
          while (true) {
            try {
              Socket sock = listenSocket.accept();
              TreeLogger branch = logger.branch(TreeLogger.TRACE,
                  "Connection received from "
                      + sock.getInetAddress().getCanonicalHostName() + ":"
                      + sock.getPort());
              try {
                sock.setTcpNoDelay(true);
                sock.setKeepAlive(true);
              } catch (SocketException e) {
                // Ignore non-critical errors.
              }

              BrowserChannelServer server = new BrowserChannelServer(branch,
                  sock, handler, ignoreRemoteDeath);
              /*
               * This object is special-cased by the SessionHandler, used for
               * methods needed by the client like hasMethod/hasProperty/etc.
               * handler is used for this object just to make sure it doesn't
               * conflict with some real object exposed to the client.
               */
              int id = server.getJavaObjectsExposedInBrowser().add(server);
              assert id == BrowserChannel.SPECIAL_SERVERMETHODS_OBJECT;
            } catch (IOException e) {
              logger.log(TreeLogger.ERROR, "Communications error", e);
            }
          }
        }
      };
      listenThread.setName("Code server listener");
      listenThread.setDaemon(true);
    } catch (BindException e) {
      logger.log(TreeLogger.ERROR, "Unable to bind socket on port " + port
          + " -- is another session active?", e);
    } catch (IOException e) {
      logger.log(TreeLogger.ERROR, "Communications error", e);
    }
  }

  /**
   * @return the port number of the listening socket.
   * 
   * @throws UnableToCompleteException if the listener is not running
   */
  public int getSocketPort() throws UnableToCompleteException {
    if (listenSocket == null) {
      // If we failed to initialize our socket, just bail here.
      throw new UnableToCompleteException();
    }
    return listenSocket.getLocalPort();
  }

  /**
   * Set any created BrowserChannelServers to ignore remote deaths.
   * 
   * <p>
   * This is most commonly wanted by JUnitShell.
   * 
   * @param ignoreRemoteDeath
   */
  public void setIgnoreRemoteDeath(boolean ignoreRemoteDeath) {
    this.ignoreRemoteDeath = ignoreRemoteDeath;
  }

  /**
   * Start the listener thread.
   */
  public void start() {
    if (listenThread != null) {
      listenThread.start();
    }
  }
}
