/*
 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import java.net.*;
import java.io.*;
import java.util.ArrayList;

/**
 * This class implements a simple FTP server that can handle multiple
 * connections concurrently. This is mostly meant as a test environment.
 * You have to provide 2 handlers for it to be effective, one to simulate
 * (or access) a filesystem and one to deal with authentication.
 * See {@link FtpFileSystemHandler} and {@link FtpAuthHandler}.
 *
 * Since it is a subclass of Thread, you have to call <code>start()</code>
 * To get it running.
 *
 * Usage example:<p>
 *
 * <code>
 * FtpServer server = new FtpServer(0);
 * int port = server.getLocalPort();
 * server.setFileSystemHandler(myFSHandler);
 * server.setAuthHandler(myAuthHandler);
 * server.start();
 * </code>
 *
 */

public class FtpServer extends Thread {
    private ServerSocket listener = null;
    private FtpFileSystemHandler fsh = null;
    private FtpAuthHandler auth = null;
    private boolean done = false;
    private ArrayList<FtpCommandHandler> clients = new ArrayList<FtpCommandHandler>();

    /**
     * Creates an instance of an FTP server which will listen for incoming
     * connections on the specified port. If the port is set to 0, it will
     * automatically select an available ephemeral port.
     */
    public FtpServer(int port) throws IOException {
        listener = new ServerSocket(port);
    }

    /**
     * Creates an instance of an FTP server that will listen on the default
     * FTP port, usually 21.
     */
    public FtpServer() throws IOException {
        this(21);
    }

    public void setFileSystemHandler(FtpFileSystemHandler f) {
        fsh = f;
    }

    public void setAuthHandler(FtpAuthHandler a) {
        auth = a;
    }

    public void terminate() {
        done = true;
        interrupt();
    }

    public void killClients() {
        synchronized (clients) {
            int c = clients.size();
            while (c > 0) {
                c--;
                FtpCommandHandler cl = clients.get(c);
                cl.terminate();
                cl.interrupt();
            }
        }
    }

    public int getLocalPort() {
        return listener.getLocalPort();
    }

    void addClient(Socket client) {
        FtpCommandHandler h = new FtpCommandHandler(client, this);
        h.setHandlers(fsh, auth);
        synchronized (clients) {
            clients.add(h);
        }
        h.start();
    }

    void removeClient(FtpCommandHandler cl) {
        synchronized (clients) {
            clients.remove(cl);
        }
    }

    public int activeClientsCount() {
        synchronized (clients) {
            return clients.size();
        }
    }

    public void run() {
        Socket client;

        try {
            while (!done) {
                client = listener.accept();
                addClient(client);
            }
            listener.close();
        } catch (IOException e) {

        }
    }
}
