/*
 * 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.
 */

package org.apache.ftpserver.impl;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.ftpserver.ftplet.FtpFile;
import org.apache.ftpserver.ftplet.User;

/**
 * <strong>Internal class, do not use directly.</strong>
 * 
 * This is FTP statistics implementation.
 * 
 * TODO revisit concurrency, right now we're a bit over zealous with both Atomic*
 * counters and synchronization
 *
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 */
public class DefaultFtpStatistics implements ServerFtpStatistics {

    private StatisticsObserver observer = null;

    private FileObserver fileObserver = null;

    private Date startTime = new Date();

    private AtomicInteger uploadCount = new AtomicInteger(0);

    private AtomicInteger downloadCount = new AtomicInteger(0);

    private AtomicInteger deleteCount = new AtomicInteger(0);

    private AtomicInteger mkdirCount = new AtomicInteger(0);

    private AtomicInteger rmdirCount = new AtomicInteger(0);

    private AtomicInteger currLogins = new AtomicInteger(0);

    private AtomicInteger totalLogins = new AtomicInteger(0);

    private AtomicInteger totalFailedLogins = new AtomicInteger(0);

    private AtomicInteger currAnonLogins = new AtomicInteger(0);

    private AtomicInteger totalAnonLogins = new AtomicInteger(0);

    private AtomicInteger currConnections = new AtomicInteger(0);

    private AtomicInteger totalConnections = new AtomicInteger(0);

    private AtomicLong bytesUpload = new AtomicLong(0L);

    private AtomicLong bytesDownload = new AtomicLong(0L);

    private static class UserLogins {
        private Map<InetAddress, AtomicInteger> perAddress = new ConcurrentHashMap<>();

        public UserLogins(InetAddress address) {
            // init with the first connection
            totalLogins = new AtomicInteger(1);
            perAddress.put(address, new AtomicInteger(1));
        }

        public AtomicInteger loginsFromInetAddress(InetAddress address) {
            AtomicInteger logins = perAddress.get(address);
            if (logins == null) {
                logins = new AtomicInteger(0);
                perAddress.put(address, logins);
            }
            return logins;
        }

        public AtomicInteger totalLogins;
    }

    /**
     *The user login information.
     */
    private Map<String, UserLogins> userLoginTable = new ConcurrentHashMap<>();

    public static final String LOGIN_NUMBER = "login_number";

    /**
     * Set the observer.
     */
    public void setObserver(final StatisticsObserver observer) {
        this.observer = observer;
    }

    /**
     * Set the file observer.
     */
    public void setFileObserver(final FileObserver observer) {
        fileObserver = observer;
    }

    // //////////////////////////////////////////////////////
    // /////////////// All getter methods /////////////////
    /**
     * Get server start time.
     */
    public Date getStartTime() {
        if (startTime != null) {
            return (Date) startTime.clone();
        } else {
            return null;
        }
    }

    /**
     * Get number of files uploaded.
     */
    public int getTotalUploadNumber() {
        return uploadCount.get();
    }

    /**
     * Get number of files downloaded.
     */
    public int getTotalDownloadNumber() {
        return downloadCount.get();
    }

    /**
     * Get number of files deleted.
     */
    public int getTotalDeleteNumber() {
        return deleteCount.get();
    }

    /**
     * Get total number of bytes uploaded.
     */
    public long getTotalUploadSize() {
        return bytesUpload.get();
    }

    /**
     * Get total number of bytes downloaded.
     */
    public long getTotalDownloadSize() {
        return bytesDownload.get();
    }

    /**
     * Get total directory created.
     */
    public int getTotalDirectoryCreated() {
        return mkdirCount.get();
    }

    /**
     * Get total directory removed.
     */
    public int getTotalDirectoryRemoved() {
        return rmdirCount.get();
    }

    /**
     * Get total number of connections.
     */
    public int getTotalConnectionNumber() {
        return totalConnections.get();
    }

    /**
     * Get current number of connections.
     */
    public int getCurrentConnectionNumber() {
        return currConnections.get();
    }

    /**
     * Get total number of logins.
     */
    public int getTotalLoginNumber() {
        return totalLogins.get();
    }

    /**
     * Get total failed login number.
     */
    public int getTotalFailedLoginNumber() {
        return totalFailedLogins.get();
    }

    /**
     * Get current number of logins.
     */
    public int getCurrentLoginNumber() {
        return currLogins.get();
    }

    /**
     * Get total number of anonymous logins.
     */
    public int getTotalAnonymousLoginNumber() {
        return totalAnonLogins.get();
    }

    /**
     * Get current number of anonymous logins.
     */
    public int getCurrentAnonymousLoginNumber() {
        return currAnonLogins.get();
    }

    /**
     * Get the login number for the specific user
     */
    public synchronized int getCurrentUserLoginNumber(final User user) {
        UserLogins userLogins = userLoginTable.get(user.getName());
        if (userLogins == null) {// not found the login user's statistics info
            return 0;
        } else {
            return userLogins.totalLogins.get();
        }
    }

    /**
     * Get the login number for the specific user from the ipAddress
     * 
     * @param user
     *            login user account
     * @param ipAddress
     *            the ip address of the remote user
     */
    public synchronized int getCurrentUserLoginNumber(final User user,
            final InetAddress ipAddress) {
        UserLogins userLogins = userLoginTable.get(user.getName());
        if (userLogins == null) {// not found the login user's statistics info
            return 0;
        } else {
            return userLogins.loginsFromInetAddress(ipAddress).get();
        }
    }

    // //////////////////////////////////////////////////////
    // /////////////// All setter methods /////////////////
    /**
     * Increment upload count.
     */
    public synchronized void setUpload(final FtpIoSession session,
            final FtpFile file, final long size) {
        uploadCount.incrementAndGet();
        bytesUpload.addAndGet(size);
        notifyUpload(session, file, size);
    }

    /**
     * Increment download count.
     */
    public synchronized void setDownload(final FtpIoSession session,
            final FtpFile file, final long size) {
        downloadCount.incrementAndGet();
        bytesDownload.addAndGet(size);
        notifyDownload(session, file, size);
    }

    /**
     * Increment delete count.
     */
    public synchronized void setDelete(final FtpIoSession session,
            final FtpFile file) {
        deleteCount.incrementAndGet();
        notifyDelete(session, file);
    }

    /**
     * Increment make directory count.
     */
    public synchronized void setMkdir(final FtpIoSession session,
            final FtpFile file) {
        mkdirCount.incrementAndGet();
        notifyMkdir(session, file);
    }

    /**
     * Increment remove directory count.
     */
    public synchronized void setRmdir(final FtpIoSession session,
            final FtpFile file) {
        rmdirCount.incrementAndGet();
        notifyRmdir(session, file);
    }

    /**
     * Increment open connection count.
     */
    public synchronized void setOpenConnection(final FtpIoSession session) {
        currConnections.incrementAndGet();
        totalConnections.incrementAndGet();
        notifyOpenConnection(session);
    }

    /**
     * Decrement open connection count.
     */
    public synchronized void setCloseConnection(final FtpIoSession session) {
        if (currConnections.get() > 0) {
            currConnections.decrementAndGet();
        }
        notifyCloseConnection(session);
    }

    /**
     * New login.
     */
    public synchronized void setLogin(final FtpIoSession session) {
        currLogins.incrementAndGet();
        totalLogins.incrementAndGet();
        User user = session.getUser();
        if ("anonymous".equals(user.getName())) {
            currAnonLogins.incrementAndGet();
            totalAnonLogins.incrementAndGet();
        }

        synchronized (user) {// thread safety is needed. Since the login occurrs
            // at low frequency, this overhead is endurable
            UserLogins statisticsTable = userLoginTable.get(user.getName());
            if (statisticsTable == null) {
                // the hash table that records the login information of the user
                // and its ip address.

                InetAddress address = null;
                if (session.getRemoteAddress() instanceof InetSocketAddress) {
                    address = ((InetSocketAddress) session.getRemoteAddress())
                            .getAddress();
                }
                statisticsTable = new UserLogins(address);
                userLoginTable.put(user.getName(), statisticsTable);
            } else {
                statisticsTable.totalLogins.incrementAndGet();

                if (session.getRemoteAddress() instanceof InetSocketAddress) {
                    InetAddress address = ((InetSocketAddress) session
                            .getRemoteAddress()).getAddress();
                    statisticsTable.loginsFromInetAddress(address)
                            .incrementAndGet();
                }

            }
        }

        notifyLogin(session);
    }

    /**
     * Increment failed login count.
     */
    public synchronized void setLoginFail(final FtpIoSession session) {
        totalFailedLogins.incrementAndGet();
        notifyLoginFail(session);
    }

    /**
     * User logout
     */
    public synchronized void setLogout(final FtpIoSession session) {
        User user = session.getUser();
        if (user == null) {
            return;
        }

        currLogins.decrementAndGet();

        if ("anonymous".equals(user.getName())) {
            currAnonLogins.decrementAndGet();
        }

        synchronized (user) {
            UserLogins userLogins = userLoginTable.get(user.getName());

            if (userLogins != null) {
                userLogins.totalLogins.decrementAndGet();
                if (session.getRemoteAddress() instanceof InetSocketAddress) {
                    InetAddress address = ((InetSocketAddress) session
                            .getRemoteAddress()).getAddress();
                    userLogins.loginsFromInetAddress(address).decrementAndGet();
                }
            }

        }

        notifyLogout(session);
    }

    // //////////////////////////////////////////////////////////
    // /////////////// all observer methods ////////////////////
    /**
     * Observer upload notification.
     */
    private void notifyUpload(final FtpIoSession session,
            final FtpFile file, long size) {
        StatisticsObserver observer = this.observer;
        if (observer != null) {
            observer.notifyUpload();
        }

        FileObserver fileObserver = this.fileObserver;
        if (fileObserver != null) {
            fileObserver.notifyUpload(session, file, size);
        }
    }

    /**
     * Observer download notification.
     */
    private void notifyDownload(final FtpIoSession session,
            final FtpFile file, final long size) {
        StatisticsObserver observer = this.observer;
        if (observer != null) {
            observer.notifyDownload();
        }

        FileObserver fileObserver = this.fileObserver;
        if (fileObserver != null) {
            fileObserver.notifyDownload(session, file, size);
        }
    }

    /**
     * Observer delete notification.
     */
    private void notifyDelete(final FtpIoSession session, final FtpFile file) {
        StatisticsObserver observer = this.observer;
        if (observer != null) {
            observer.notifyDelete();
        }

        FileObserver fileObserver = this.fileObserver;
        if (fileObserver != null) {
            fileObserver.notifyDelete(session, file);
        }
    }

    /**
     * Observer make directory notification.
     */
    private void notifyMkdir(final FtpIoSession session, final FtpFile file) {
        StatisticsObserver observer = this.observer;
        if (observer != null) {
            observer.notifyMkdir();
        }

        FileObserver fileObserver = this.fileObserver;
        if (fileObserver != null) {
            fileObserver.notifyMkdir(session, file);
        }
    }

    /**
     * Observer remove directory notification.
     */
    private void notifyRmdir(final FtpIoSession session, final FtpFile file) {
        StatisticsObserver observer = this.observer;
        if (observer != null) {
            observer.notifyRmdir();
        }

        FileObserver fileObserver = this.fileObserver;
        if (fileObserver != null) {
            fileObserver.notifyRmdir(session, file);
        }
    }

    /**
     * Observer open connection notification.
     */
    private void notifyOpenConnection(final FtpIoSession session) {
        StatisticsObserver observer = this.observer;
        if (observer != null) {
            observer.notifyOpenConnection();
        }
    }

    /**
     * Observer close connection notification.
     */
    private void notifyCloseConnection(final FtpIoSession session) {
        StatisticsObserver observer = this.observer;
        if (observer != null) {
            observer.notifyCloseConnection();
        }
    }

    /**
     * Observer login notification.
     */
    private void notifyLogin(final FtpIoSession session) {
        StatisticsObserver observer = this.observer;
        if (observer != null) {

            // is anonymous login
            User user = session.getUser();
            boolean anonymous = false;
            if (user != null) {
                String login = user.getName();
                anonymous = (login != null) && login.equals("anonymous");
            }
            observer.notifyLogin(anonymous);
        }
    }

    /**
     * Observer failed login notification.
     */
    private void notifyLoginFail(final FtpIoSession session) {
        StatisticsObserver observer = this.observer;
        if (observer != null) {
            if (session.getRemoteAddress() instanceof InetSocketAddress) {
                observer.notifyLoginFail(((InetSocketAddress) session
                        .getRemoteAddress()).getAddress());

            }
        }
    }

    /**
     * Observer logout notification.
     */
    private void notifyLogout(final FtpIoSession session) {
        StatisticsObserver observer = this.observer;
        if (observer != null) {
            // is anonymous login
            User user = session.getUser();
            boolean anonymous = false;
            if (user != null) {
                String login = user.getName();
                anonymous = (login != null) && login.equals("anonymous");
            }
            observer.notifyLogout(anonymous);
        }
    }

    /**
     * Reset the cumulative counters.
     */
    public synchronized void resetStatisticsCounters() {
        startTime = new Date();

        uploadCount.set(0);
        downloadCount.set(0);
        deleteCount.set(0);

        mkdirCount.set(0);
        rmdirCount.set(0);

        totalLogins.set(0);
        totalFailedLogins.set(0);
        totalAnonLogins.set(0);
        totalConnections.set(0);

        bytesUpload.set(0);
        bytesDownload.set(0);
    }
}
