/*
 * Copyright 2007 the original author or authors.
 * 
 * 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 org.mockftpserver.stub;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.mockftpserver.core.command.CommandHandler;
import org.mockftpserver.core.command.CommandNames;
import org.mockftpserver.core.command.InvocationRecord;
import org.mockftpserver.core.command.SimpleCompositeCommandHandler;
import org.mockftpserver.core.command.StaticReplyCommandHandler;
import org.mockftpserver.stub.command.*;
import org.mockftpserver.test.*;
import org.mockftpserver.test.AbstractTestCase;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Tests for StubFtpServer using the Apache Jakarta Commons Net FTP client.
 *
 * @author Chris Mair
 * @version $Revision$ - $Date$
 */
public final class StubFtpServerIntegrationTest extends AbstractTestCase implements IntegrationTest {

    private static final Logger LOG = LoggerFactory.getLogger(StubFtpServerIntegrationTest.class);
    private static final String SERVER = "localhost";
    private static final String USERNAME = "user123";
    private static final String PASSWORD = "password";
    private static final String FILENAME = "abc.txt";
    private static final String ASCII_CONTENTS = "abcdef\tghijklmnopqr";
    private static final byte[] BINARY_CONTENTS = new byte[256];

    private StubFtpServer stubFtpServer;
    private FTPClient ftpClient;
    private RetrCommandHandler retrCommandHandler;
    private StorCommandHandler storCommandHandler;

    //-------------------------------------------------------------------------
    // Tests
    //-------------------------------------------------------------------------

    public void testLogin() throws Exception {
        // Connect
        LOG.info("Conecting to " + SERVER);
        ftpClientConnect();
        verifyReplyCode("connect", 220);

        // Login
        String userAndPassword = USERNAME + "/" + PASSWORD;
        LOG.info("Logging in as " + userAndPassword);
        boolean success = ftpClient.login(USERNAME, PASSWORD);
        assertTrue("Unable to login with " + userAndPassword, success);
        verifyReplyCode("login with " + userAndPassword, 230);

        assertTrue("isStarted", stubFtpServer.isStarted());
        assertFalse("isShutdown", stubFtpServer.isShutdown());

        // Quit
        LOG.info("Quit");
        ftpClient.quit();
        verifyReplyCode("quit", 221);
    }

    public void testAcct() throws Exception {
        ftpClientConnect();

        // ACCT
        int replyCode = ftpClient.acct("123456");
        assertEquals("acct", 230, replyCode);
    }

    /**
     * Test the stop() method when no session has ever been started
     */
    public void testStop_NoSessionEverStarted() throws Exception {
        LOG.info("Testing a stop() when no session has ever been started");
    }

    public void testHelp() throws Exception {
        // Modify HELP CommandHandler to return a predefined help message
        final String HELP = "help message";
        HelpCommandHandler helpCommandHandler = (HelpCommandHandler) stubFtpServer.getCommandHandler(CommandNames.HELP);
        helpCommandHandler.setHelpMessage(HELP);

        ftpClientConnect();

        // HELP
        String help = ftpClient.listHelp();
        assertTrue("Wrong response", help.indexOf(HELP) != -1);
        verifyReplyCode("listHelp", 214);
    }

    /**
     * Test the LIST and SYST commands.
     */
    public void testList() throws Exception {
        ftpClientConnect();

        // Set directory listing
        ListCommandHandler listCommandHandler = (ListCommandHandler) stubFtpServer.getCommandHandler(CommandNames.LIST);
        listCommandHandler.setDirectoryListing("11-09-01 12:30PM  406348 File2350.log\n"
                + "11-01-01 1:30PM <DIR>  archive");

        // LIST
        FTPFile[] files = ftpClient.listFiles();
        assertEquals("number of files", 2, files.length);
        verifyFTPFile(files[0], FTPFile.FILE_TYPE, "File2350.log", 406348L);
        verifyFTPFile(files[1], FTPFile.DIRECTORY_TYPE, "archive", 0L);
        verifyReplyCode("list", 226);
    }

    /**
     * Test the LIST, PASV and SYST commands, transferring a directory listing in passive mode
     */
    public void testList_PassiveMode() throws Exception {
        ftpClientConnect();

        ftpClient.enterLocalPassiveMode();

        // Set directory listing
        ListCommandHandler listCommandHandler = (ListCommandHandler) stubFtpServer.getCommandHandler(CommandNames.LIST);
        listCommandHandler.setDirectoryListing("11-09-01 12:30PM  406348 File2350.log");

        // LIST
        FTPFile[] files = ftpClient.listFiles();
        assertEquals("number of files", 1, files.length);
        verifyReplyCode("list", 226);
    }

    public void testNlst() throws Exception {
        ftpClientConnect();

        // Set directory listing
        NlstCommandHandler nlstCommandHandler = (NlstCommandHandler) stubFtpServer.getCommandHandler(CommandNames.NLST);
        nlstCommandHandler.setDirectoryListing("File1.txt\nfile2.data");

        // NLST
        String[] filenames = ftpClient.listNames();
        assertEquals("number of files", 2, filenames.length);
        assertEquals(filenames[0], "File1.txt");
        assertEquals(filenames[1], "file2.data");
        verifyReplyCode("listNames", 226);
    }

    /**
     * Test printing the current working directory (PWD)
     */
    public void testPwd() throws Exception {
        // Modify PWD CommandHandler to return a predefined directory
        final String DIR = "some/dir";
        PwdCommandHandler pwdCommandHandler = (PwdCommandHandler) stubFtpServer.getCommandHandler(CommandNames.PWD);
        pwdCommandHandler.setDirectory(DIR);

        ftpClientConnect();

        // PWD
        String dir = ftpClient.printWorkingDirectory();
        assertEquals("Unable to PWD", DIR, dir);
        verifyReplyCode("printWorkingDirectory", 257);
    }

    public void testStat() throws Exception {
        // Modify Stat CommandHandler to return predefined text
        final String STATUS = "some information 123";
        StatCommandHandler statCommandHandler = (StatCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STAT);
        statCommandHandler.setStatus(STATUS);

        ftpClientConnect();

        // STAT
        String status = ftpClient.getStatus();
        assertEquals("STAT reply", "211 " + STATUS + ".", status.trim());
        verifyReplyCode("getStatus", 211);
    }

    /**
     * Test getting the status (STAT), when the reply text contains multiple lines
     */
    public void testStat_MultilineReplyText() throws Exception {
        // Modify Stat CommandHandler to return predefined text
        final String STATUS = "System name: abc.def\nVersion 3.5.7\nNumber of failed logins: 2";
        final String FORMATTED_REPLY_STATUS = "211-System name: abc.def\r\nVersion 3.5.7\r\n211 Number of failed logins: 2.";
        StatCommandHandler statCommandHandler = (StatCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STAT);
        statCommandHandler.setStatus(STATUS);

        ftpClientConnect();

        // STAT
        String status = ftpClient.getStatus();
        assertEquals("STAT reply", FORMATTED_REPLY_STATUS, status.trim());
        verifyReplyCode("getStatus", 211);
    }

    public void testSyst() throws Exception {
        ftpClientConnect();

        // SYST
        assertEquals("getSystemName()", "\"WINDOWS\" system type.", ftpClient.getSystemName());
        verifyReplyCode("syst", 215);
    }

    public void testCwd() throws Exception {
        // Connect
        LOG.info("Conecting to " + SERVER);
        ftpClientConnect();
        verifyReplyCode("connect", 220);

        // CWD
        boolean success = ftpClient.changeWorkingDirectory("dir1/dir2");
        assertTrue("Unable to CWD", success);
        verifyReplyCode("changeWorkingDirectory", 250);
    }

    /**
     * Test changing the current working directory (CWD), when it causes a remote error
     */
    public void testCwd_Error() throws Exception {
        // Override CWD CommandHandler to return error reply code
        final int REPLY_CODE = 500;
        StaticReplyCommandHandler cwdCommandHandler = new StaticReplyCommandHandler(REPLY_CODE);
        stubFtpServer.setCommandHandler("CWD", cwdCommandHandler);

        ftpClientConnect();

        // CWD
        boolean success = ftpClient.changeWorkingDirectory("dir1/dir2");
        assertFalse("Expected failure", success);
        verifyReplyCode("changeWorkingDirectory", REPLY_CODE);
    }

    public void testCdup() throws Exception {
        ftpClientConnect();

        // CDUP
        boolean success = ftpClient.changeToParentDirectory();
        assertTrue("Unable to CDUP", success);
        verifyReplyCode("changeToParentDirectory", 200);
    }

    public void testDele() throws Exception {
        ftpClientConnect();

        // DELE
        boolean success = ftpClient.deleteFile(FILENAME);
        assertTrue("Unable to DELE", success);
        verifyReplyCode("deleteFile", 250);
    }

    public void testEprt() throws Exception {
        LOG.info("Skipping...");
//        ftpClientConnect();
//        ftpClient.sendCommand("EPRT", "|2|1080::8:800:200C:417A|5282|");
//        verifyReplyCode("EPRT", 200);
    }

    public void testEpsv() throws Exception {
        ftpClientConnect();
        ftpClient.sendCommand("EPSV");
        verifyReplyCode("EPSV", 229);
    }
    
    public void testFeat_UseStaticReplyCommandHandler() throws IOException {
        // The FEAT command is not supported out of the box
        final String FEAT_TEXT = "Extensions supported:\n" +
                "MLST size*;create;modify*;perm;media-type\n" +
                "SIZE\n" +
                "COMPRESSION\n" +
                "END";
        StaticReplyCommandHandler featCommandHandler = new StaticReplyCommandHandler(211, FEAT_TEXT);
        stubFtpServer.setCommandHandler("FEAT", featCommandHandler);

        ftpClientConnect();
        assertEquals(ftpClient.sendCommand("FEAT"), 211);
        LOG.info(ftpClient.getReplyString());
    }

    public void testMkd() throws Exception {
        ftpClientConnect();

        // MKD
        boolean success = ftpClient.makeDirectory("dir1/dir2");
        assertTrue("Unable to CWD", success);
        verifyReplyCode("makeDirectory", 257);
    }

    public void testNoop() throws Exception {
        ftpClientConnect();

        // NOOP
        boolean success = ftpClient.sendNoOp();
        assertTrue("Unable to NOOP", success);
        verifyReplyCode("NOOP", 200);
    }

    public void testRest() throws Exception {
        ftpClientConnect();

        // REST
        int replyCode = ftpClient.rest("marker");
        assertEquals("Unable to REST", 350, replyCode);
    }

    public void testRmd() throws Exception {
        ftpClientConnect();

        // RMD
        boolean success = ftpClient.removeDirectory("dir1/dir2");
        assertTrue("Unable to RMD", success);
        verifyReplyCode("removeDirectory", 250);
    }

    public void testRename() throws Exception {
        ftpClientConnect();

        // Rename (RNFR, RNTO)
        boolean success = ftpClient.rename(FILENAME, "new_" + FILENAME);
        assertTrue("Unable to RENAME", success);
        verifyReplyCode("rename", 250);
    }

    public void testAllo() throws Exception {
        ftpClientConnect();

        // ALLO
        assertTrue("ALLO", ftpClient.allocate(1024));
        assertTrue("ALLO with recordSize", ftpClient.allocate(1024, 64));
    }

    /**
     * Test GET and PUT of ASCII files
     */
    public void testTransferAsciiFile() throws Exception {
        retrCommandHandler.setFileContents(ASCII_CONTENTS);

        ftpClientConnect();

        // Get File
        LOG.info("Get File for remotePath [" + FILENAME + "]");
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        assertTrue(ftpClient.retrieveFile(FILENAME, outputStream));
        LOG.info("File contents=[" + outputStream.toString());
        assertEquals("File contents", ASCII_CONTENTS, outputStream.toString());

        // Put File
        LOG.info("Put File for local path [" + FILENAME + "]");
        ByteArrayInputStream inputStream = new ByteArrayInputStream(ASCII_CONTENTS.getBytes());
        assertTrue(ftpClient.storeFile(FILENAME, inputStream));
        InvocationRecord invocationRecord = storCommandHandler.getInvocation(0);
        byte[] contents = (byte[]) invocationRecord.getObject(StorCommandHandler.FILE_CONTENTS_KEY);
        LOG.info("File contents=[" + contents + "]");
        assertEquals("File contents", ASCII_CONTENTS.getBytes(), contents);
    }

    /**
     * Test GET and PUT of binary files
     */
    public void testTransferBinaryFiles() throws Exception {
        retrCommandHandler.setFileContents(BINARY_CONTENTS);

        ftpClientConnect();
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

        // Get File
        LOG.info("Get File for remotePath [" + FILENAME + "]");
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        assertTrue("GET", ftpClient.retrieveFile(FILENAME, outputStream));
        LOG.info("GET File length=" + outputStream.size());
        assertEquals("File contents", BINARY_CONTENTS, outputStream.toByteArray());

        // Put File
        LOG.info("Put File for local path [" + FILENAME + "]");
        ByteArrayInputStream inputStream = new ByteArrayInputStream(BINARY_CONTENTS);
        assertTrue("PUT", ftpClient.storeFile(FILENAME, inputStream));
        InvocationRecord invocationRecord = storCommandHandler.getInvocation(0);
        byte[] contents = (byte[]) invocationRecord.getObject(StorCommandHandler.FILE_CONTENTS_KEY);
        LOG.info("PUT File length=" + contents.length);
        assertEquals("File contents", BINARY_CONTENTS, contents);
    }

    public void testStou() throws Exception {
        StouCommandHandler stouCommandHandler = (StouCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STOU);
        stouCommandHandler.setFilename(FILENAME);

        ftpClientConnect();

        // Stor a File (STOU)
        ByteArrayInputStream inputStream = new ByteArrayInputStream(ASCII_CONTENTS.getBytes());
        assertTrue(ftpClient.storeUniqueFile(FILENAME, inputStream));
        InvocationRecord invocationRecord = stouCommandHandler.getInvocation(0);
        byte[] contents = (byte[]) invocationRecord.getObject(StorCommandHandler.FILE_CONTENTS_KEY);
        LOG.info("File contents=[" + contents + "]");
        assertEquals("File contents", ASCII_CONTENTS.getBytes(), contents);
    }

    public void testAppe() throws Exception {
        AppeCommandHandler appeCommandHandler = (AppeCommandHandler) stubFtpServer.getCommandHandler(CommandNames.APPE);

        ftpClientConnect();

        // Append a File (APPE)
        ByteArrayInputStream inputStream = new ByteArrayInputStream(ASCII_CONTENTS.getBytes());
        assertTrue(ftpClient.appendFile(FILENAME, inputStream));
        InvocationRecord invocationRecord = appeCommandHandler.getInvocation(0);
        byte[] contents = (byte[]) invocationRecord.getObject(AppeCommandHandler.FILE_CONTENTS_KEY);
        LOG.info("File contents=[" + contents + "]");
        assertEquals("File contents", ASCII_CONTENTS.getBytes(), contents);
    }

    public void testAbor() throws Exception {
        ftpClientConnect();

        // ABOR
        assertTrue("ABOR", ftpClient.abort());
    }

    public void testPasv() throws Exception {
        ftpClientConnect();

        // PASV
        ftpClient.enterLocalPassiveMode();
        // no reply code; the PASV command is sent only when the data connection is opened 
    }

    public void testMode() throws Exception {
        ftpClientConnect();

        // MODE
        boolean success = ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
        assertTrue("Unable to MODE", success);
        verifyReplyCode("setFileTransferMode", 200);
    }

    public void testStru() throws Exception {
        ftpClientConnect();

        // STRU
        boolean success = ftpClient.setFileStructure(FTP.FILE_STRUCTURE);
        assertTrue("Unable to STRU", success);
        verifyReplyCode("setFileStructure", 200);
    }

    public void testSimpleCompositeCommandHandler() throws Exception {
        // Replace CWD CommandHandler with a SimpleCompositeCommandHandler
        CommandHandler commandHandler1 = new StaticReplyCommandHandler(500);
        CommandHandler commandHandler2 = new CwdCommandHandler();
        SimpleCompositeCommandHandler simpleCompositeCommandHandler = new SimpleCompositeCommandHandler();
        simpleCompositeCommandHandler.addCommandHandler(commandHandler1);
        simpleCompositeCommandHandler.addCommandHandler(commandHandler2);
        stubFtpServer.setCommandHandler("CWD", simpleCompositeCommandHandler);

        // Connect
        ftpClientConnect();

        // CWD
        assertFalse("first", ftpClient.changeWorkingDirectory("dir1/dir2"));
        assertTrue("first", ftpClient.changeWorkingDirectory("dir1/dir2"));
    }

    public void testSite() throws Exception {
        ftpClientConnect();

        // SITE
        int replyCode = ftpClient.site("parameters,1,2,3");
        assertEquals("SITE", 200, replyCode);
    }

    public void testSmnt() throws Exception {
        ftpClientConnect();

        // SMNT
        assertTrue("SMNT", ftpClient.structureMount("dir1/dir2"));
        verifyReplyCode("structureMount", 250);
    }

    public void testRein() throws Exception {
        ftpClientConnect();

        // REIN
        assertEquals("REIN", 220, ftpClient.rein());
    }

    /**
     * Test that command names in lowercase or mixed upper/lower case are accepted
     */
    public void testCommandNamesInLowerOrMixedCase() throws Exception {
        ftpClientConnect();

        assertEquals("rein", 220, ftpClient.sendCommand("rein"));
        assertEquals("rEIn", 220, ftpClient.sendCommand("rEIn"));
        assertEquals("reiN", 220, ftpClient.sendCommand("reiN"));
        assertEquals("Rein", 220, ftpClient.sendCommand("Rein"));
    }

    public void testUnrecognizedCommand() throws Exception {
        ftpClientConnect();

        assertEquals("Unrecognized:XXXX", 502, ftpClient.sendCommand("XXXX"));
    }

    // -------------------------------------------------------------------------
    // Test setup and tear-down
    // -------------------------------------------------------------------------

    /**
     * Perform initialization before each test
     *
     * @see org.mockftpserver.test.AbstractTestCase#setUp()
     */
    protected void setUp() throws Exception {
        super.setUp();

        for (int i = 0; i < BINARY_CONTENTS.length; i++) {
            BINARY_CONTENTS[i] = (byte) i;
        }

        stubFtpServer = new StubFtpServer();
        stubFtpServer.setServerControlPort(PortTestUtil.getFtpServerControlPort());
        stubFtpServer.start();
        ftpClient = new FTPClient();
        retrCommandHandler = (RetrCommandHandler) stubFtpServer.getCommandHandler(CommandNames.RETR);
        storCommandHandler = (StorCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STOR);
    }

    /**
     * Perform cleanup after each test
     *
     * @see org.mockftpserver.test.AbstractTestCase#tearDown()
     */
    protected void tearDown() throws Exception {
        super.tearDown();
        stubFtpServer.stop();
    }

    // -------------------------------------------------------------------------
    // Internal Helper Methods
    // -------------------------------------------------------------------------

    /**
     * Connect to the server from the FTPClient
     */
    private void ftpClientConnect() throws IOException {
        ftpClient.connect(SERVER, PortTestUtil.getFtpServerControlPort());
    }

    /**
     * Assert that the FtpClient reply code is equal to the expected value
     *
     * @param operation         - the description of the operation performed; used in the error message
     * @param expectedReplyCode - the expected FtpClient reply code
     */
    private void verifyReplyCode(String operation, int expectedReplyCode) {
        int replyCode = ftpClient.getReplyCode();
        LOG.info("Reply: operation=\"" + operation + "\" replyCode=" + replyCode);
        assertEquals("Unexpected replyCode for " + operation, expectedReplyCode, replyCode);
    }

    /**
     * Verify that the FTPFile has the specified properties
     *
     * @param ftpFile - the FTPFile to verify
     * @param type    - the expected file type
     * @param name    - the expected file name
     * @param size    - the expected file size (will be zero for a directory)
     */
    private void verifyFTPFile(FTPFile ftpFile, int type, String name, long size) {
        LOG.info(ftpFile.toString());
        assertEquals("type: " + ftpFile, type, ftpFile.getType());
        assertEquals("name: " + ftpFile, name, ftpFile.getName());
        assertEquals("size: " + ftpFile, size, ftpFile.getSize());
    }

}
