/*
 * 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.io.IOException;
import java.nio.charset.MalformedInputException;

import org.apache.ftpserver.command.Command;
import org.apache.ftpserver.command.CommandFactory;
import org.apache.ftpserver.ftplet.DefaultFtpReply;
import org.apache.ftpserver.ftplet.FileSystemView;
import org.apache.ftpserver.ftplet.FtpReply;
import org.apache.ftpserver.ftplet.FtpRequest;
import org.apache.ftpserver.ftplet.FtpletResult;
import org.apache.ftpserver.ftpletcontainer.FtpletContainer;
import org.apache.ftpserver.listener.Listener;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.write.WriteToClosedSessionException;
import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <strong>Internal class, do not use directly.</strong>
 * 
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 *
 */
public class DefaultFtpHandler implements FtpHandler {

    private final Logger LOG = LoggerFactory.getLogger(DefaultFtpHandler.class);

    private final static String[] NON_AUTHENTICATED_COMMANDS = new String[] {
            "USER", "PASS", "AUTH", "QUIT", "PROT", "PBSZ" };

    private FtpServerContext context;

    private Listener listener;

    public void init(final FtpServerContext context, final Listener listener) {
        this.context = context;
        this.listener = listener;
    }

    public void sessionCreated(final FtpIoSession session) throws Exception {
        session.setListener(listener);
        
        ServerFtpStatistics stats = ((ServerFtpStatistics) context
                .getFtpStatistics());

        if (stats != null) {
            stats.setOpenConnection(session);
        }
    }

    public void sessionOpened(final FtpIoSession session) throws Exception {
        FtpletContainer ftplets = context.getFtpletContainer();

        FtpletResult ftpletRet;
        try {
            ftpletRet = ftplets.onConnect(session.getFtpletSession());
        } catch (Exception e) {
            LOG.debug("Ftplet threw exception", e);
            ftpletRet = FtpletResult.DISCONNECT;
        }
        if (ftpletRet == FtpletResult.DISCONNECT) {
            LOG.debug("Ftplet returned DISCONNECT, session will be closed");
            session.close(false).awaitUninterruptibly(10000);
        } else {
            session.updateLastAccessTime();
            
            session.write(LocalizedFtpReply.translate(session, null, context,
                    FtpReply.REPLY_220_SERVICE_READY, null, null));
        }
    }

    public void sessionClosed(final FtpIoSession session) throws Exception {
        LOG.debug("Closing session");
        try {
            context.getFtpletContainer().onDisconnect(
                    session.getFtpletSession());
        } catch (Exception e) {
            // swallow the exception, we're closing down the session anyways
            LOG.warn("Ftplet threw an exception on disconnect", e);
        }

        // make sure we close the data connection if it happens to be open
        try {
            ServerDataConnectionFactory dc = session.getDataConnection(); 
            if(dc != null) {
                dc.closeDataConnection();
            }
        } catch (Exception e) {
            // swallow the exception, we're closing down the session anyways
            LOG.warn("Data connection threw an exception on disconnect", e);
        }
        
        FileSystemView fs = session.getFileSystemView();
        if(fs != null) {
            try  {
                fs.dispose();
            } catch (Exception e) {
                LOG.warn("FileSystemView threw an exception on disposal", e);
            }
        }

        ServerFtpStatistics stats = ((ServerFtpStatistics) context
                .getFtpStatistics());

        if (stats != null) {
            stats.setLogout(session);
            stats.setCloseConnection(session);
            LOG.debug("Statistics login and connection count decreased due to session close");
        } else {
            LOG.warn("Statistics not available in session, can not decrease login and connection count");
        }
        LOG.debug("Session closed");
    }

    public void exceptionCaught(final FtpIoSession session,
            final Throwable cause) throws Exception {
        
        if(cause instanceof ProtocolDecoderException &&
                cause.getCause() instanceof MalformedInputException) {
            // client probably sent something which is not UTF-8 and we failed to
            // decode it
            
            LOG.warn(
                    "Client sent command that could not be decoded: {}",
                    ((ProtocolDecoderException)cause).getHexdump());
            session.write(new DefaultFtpReply(FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "Invalid character in command"));
        } else if (cause instanceof WriteToClosedSessionException) {
            WriteToClosedSessionException writeToClosedSessionException = 
                (WriteToClosedSessionException) cause;
            LOG.warn(
                            "Client closed connection before all replies could be sent, last reply was {}",
                            writeToClosedSessionException.getRequest());
            session.close(false).awaitUninterruptibly(10000);
        } else {
            LOG.error("Exception caught, closing session", cause);
            session.close(false).awaitUninterruptibly(10000);
        }


    }

    private boolean isCommandOkWithoutAuthentication(String command) {
        boolean okay = false;
        for (String allowed : NON_AUTHENTICATED_COMMANDS) {
            if (allowed.equals(command)) {
                okay = true;
                break;
            }
        }
        return okay;
    }

    public void messageReceived(final FtpIoSession session,
            final FtpRequest request) throws Exception {
        try {
            session.updateLastAccessTime();
            
            String commandName = request.getCommand();
            CommandFactory commandFactory = context.getCommandFactory();
            Command command = commandFactory.getCommand(commandName);

            // make sure the user is authenticated before he issues commands
            if (!session.isLoggedIn()
                    && !isCommandOkWithoutAuthentication(commandName)) {
                session.write(LocalizedFtpReply.translate(session, request,
                        context, FtpReply.REPLY_530_NOT_LOGGED_IN,
                        "permission", null));
                return;
            }

            FtpletContainer ftplets = context.getFtpletContainer();

            FtpletResult ftpletRet;
            try {
                ftpletRet = ftplets.beforeCommand(session.getFtpletSession(),
                        request);
            } catch (Exception e) {
                LOG.debug("Ftplet container threw exception", e);
                ftpletRet = FtpletResult.DISCONNECT;
            }
            if (ftpletRet == FtpletResult.DISCONNECT) {
                LOG.debug("Ftplet returned DISCONNECT, session will be closed");
                session.close(false).awaitUninterruptibly(10000);
                return;
            } else if (ftpletRet != FtpletResult.SKIP) {

                if (command != null) {
                    synchronized (session) {
                        command.execute(session, context, request);
                    }
                } else {
                    session.write(LocalizedFtpReply.translate(session, request,
                            context,
                            FtpReply.REPLY_502_COMMAND_NOT_IMPLEMENTED,
                            "not.implemented", null));
                }

                try {
                    ftpletRet = ftplets.afterCommand(
                            session.getFtpletSession(), request, session
                                    .getLastReply());
                } catch (Exception e) {
                    LOG.debug("Ftplet container threw exception", e);
                    ftpletRet = FtpletResult.DISCONNECT;
                }
                if (ftpletRet == FtpletResult.DISCONNECT) {
                    LOG.debug("Ftplet returned DISCONNECT, session will be closed");

                    session.close(false).awaitUninterruptibly(10000);
                    return;
                }
            }

        } catch (Exception ex) {
            // send error reply
            try {
                session.write(LocalizedFtpReply.translate(session, request,
                        context, FtpReply.REPLY_550_REQUESTED_ACTION_NOT_TAKEN,
                        null, null));
            } catch (Exception ex1) {
            }

            if (ex instanceof java.io.IOException) {
                throw (IOException) ex;
            } else {
                LOG.warn("RequestHandler.service()", ex);
            }
        }

    }

    public void sessionIdle(final FtpIoSession session, final IdleStatus status)
            throws Exception {
        LOG.info("Session idle, closing");
        session.close(false).awaitUninterruptibly(10000);
    }

    public void messageSent(final FtpIoSession session, final FtpReply reply)
            throws Exception {
        // do nothing

    }
}
