/*
 * 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));

      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();
    }
  }
}
