/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/***
 * Java TelnetD library (embeddable telnet daemon)
 * Copyright (c) 2000-2005 Dieter Wimberger
 * All rights reserved.
 * <p/>
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * <p/>
 * Neither the name of the author nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 * <p/>
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 ***/

package org.apache.felix.gogo.jline.telnet;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Class that implements a <tt>PortListener</tt>.<br>
 * If available, it accepts incoming connections and passes them
 * to an associated <tt>ConnectionManager</tt>.
 *
 * @author Dieter Wimberger
 * @version 2.0 (16/07/2006)
 * @see ConnectionManager
 */
public class PortListener
        implements Runnable {

    private static final Logger LOG = Logger.getLogger(PortListener.class.getName());
    private static final String logmsg =
            "Listening to Port {0,number,integer} with a connectivity queue size of {1,number,integer}.";
    private String name;
    private int port;                                        //port number running on
    private int floodProtection;                        //flooding protection
    private ServerSocket serverSocket = null; //server socket
    private Thread thread;
    private ConnectionManager connectionManager;    //connection management thread
    private boolean stopping = false;
    private boolean available;                    //Flag for availability

    /**
     * Constructs a PortListener instance.<br>
     *
     * @param port      int that specifies the port number of the server socket.
     * @param floodprot that specifies the server socket queue size.
     */
    public PortListener(String name, int port, int floodprot) {
        this.name = name;
        available = false;
        this.port = port;
        floodProtection = floodprot;
    }//constructor

    /**
     * Returns the name of this <tt>PortListener</tt>.
     *
     * @return the name as <tt>String</tt>.
     */
    public String getName() {
        return name;
    }//getName

    /**
     * Tests if this <tt>PortListener</tt> is available.
     *
     * @return true if available, false otherwise.
     */
    public boolean isAvailable() {
        return available;
    }//isAvailable

    /**
     * Sets the availability flag of this <tt>PortListener</tt>.
     *
     * @param b true if to be available, false otherwise.
     */
    public void setAvailable(boolean b) {
        available = b;
    }//setAvailable

    /**
     * Starts this <tt>PortListener</tt>.
     */
    public void start() {
        LOG.log(Level.FINE, "start()");
        thread = new Thread(this);
        thread.start();
        available = true;
    }//start

    /**
     * Stops this <tt>PortListener</tt>, and returns
     * when everything was stopped successfully.
     */
    public void stop() {
        LOG.log(Level.FINE, "stop()::" + this.toString());
        //flag stop
        stopping = true;
        available = false;
        //take down all connections
        connectionManager.stop();

        //close server socket
        try {
            serverSocket.close();
        } catch (IOException ex) {
            LOG.log(Level.SEVERE, "stop()", ex);
        }

        //wait for thread to die
        try {
            thread.join();
        } catch (InterruptedException iex) {
            LOG.log(Level.SEVERE, "stop()", iex);
        }

        LOG.info("stop()::Stopped " + this.toString());
    }//stop

    /**
     * Listen constantly to a server socket and handles incoming connections
     * through the associated {a:link ConnectionManager}.
     *
     * @see ConnectionManager
     */
    public void run() {
        try {
            /*
                A server socket is opened with a connectivity queue of a size specified
                in int floodProtection.  Concurrent login handling under normal circumstances
                should be handled properly, but denial of service attacks via massive parallel
                program logins should be prevented with this.
            */
            serverSocket = new ServerSocket(port, floodProtection);

            //log entry
            LOG.info(MessageFormat.format(logmsg, port, floodProtection));

            do {
                try {
                    Socket s = serverSocket.accept();
                    if (available) {
                        connectionManager.makeConnection(s);
                    } else {
                        //just shut down the socket
                        s.close();
                    }
                } catch (SocketException ex) {
                    if (stopping) {
                        //server socket was closed blocked in accept
                        LOG.log(Level.FINE, "run(): ServerSocket closed by stop()");
                    } else {
                        LOG.log(Level.SEVERE, "run()", ex);
                    }
                }
            } while (!stopping);

        } catch (IOException e) {
            LOG.log(Level.SEVERE, "run()", e);
        }
        LOG.log(Level.FINE, "run(): returning.");
    }//run

    /**
     * Returns reference to ConnectionManager instance associated
     * with the PortListener.
     *
     * @return the associated ConnectionManager.
     */
    public ConnectionManager getConnectionManager() {
        return connectionManager;
    }//getConnectionManager

    public void setConnectionManager(ConnectionManager connectionManager) {
        this.connectionManager = connectionManager;
    }

}//class PortListener
