/*
    Copyright (c) 2005-2013 Leisenfels. All rights reserved.
    Use is subject to license terms.
*/

package com.lf.vfslib.test;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.VFS;
import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;

import java.io.InputStream;
import java.io.OutputStream;


/**
 * Example class showing how a FTP file is copied over to a SFTP server.
 * <p/>
 * Required libraries in classpath:
 * <code>
 * commons-vfs-2.0.jar          Original Apache VFS 2.0 library
 * commons-logging-1.1.jar      Required for VFS 2.0
 * commons-net-3.3.jar          Required for FTP
 * jsch-0.1.44.jar              Required for SFTP
 * </code>
 * <p/>
 * @author Axel Schwolow
 * @version $Revision: 1.1 $, $Date: 2013/10/04 13:21:23 $
 * @since 1.6
 */
public class ExampleVFS {


    /**
     * Constructor method.
     * <p/>
     * @param host     SFTP server address
     * @param username SFTP username
     * @param password SFTP user password
     * @param port     SFTP port (optional, default: 22)
     * @param path     SFTP subdirectory (optional)
     * @throws FileSystemException Error indication
     * @since 1.6
     */
    public ExampleVFS (String host, String username, String password, String port, String path) throws FileSystemException {

        System.out.println("Configuring VFS:");
        System.out.println("    host               " + host);
        System.out.println("    username           " + username);
        System.out.println("    password           " + password);
        System.out.println("    port               " + port);
        System.out.println("    path               " + path);

        // We use the default file system manager here
        DefaultFileSystemManager fsmanager = (DefaultFileSystemManager) VFS.getManager();

        // Connect to anonymous FTP server, copy file over to SFTP server
        String ftpuri = "ftp://kernel.org/pub/site/README";
        String sftpuri = "sftp://" + username + ":" + password + "@" + host;
        if (port != null) sftpuri += ":" + port;
        if (path != null) sftpuri += path;
        sftpuri += "/README";
        // e.g. "sftp://scott:tiger@mycompany.com:22/mydir/README"

        // SFTP needs a little configuring
        FileSystemOptions options = new FileSystemOptions();
        SftpFileSystemConfigBuilder builder = SftpFileSystemConfigBuilder.getInstance();
        builder.setStrictHostKeyChecking(options, "no");  // Loose checking
        builder.setUserDirIsRoot(options, false);         // "/" is root

        System.out.println("Copying FTP file " + ftpuri + " over to SFTP file " + sftpuri);
        boolean success = false;
        try {
            // Open input stream for FTP file (read from)
            FileObject ftpobj = fsmanager.resolveFile(ftpuri);  // Throws
            InputStream istream = ftpobj.getContent().getInputStream();

            // Open output stream for SFTP file (write into)
            FileObject sftpobj = fsmanager.resolveFile(sftpuri, options);  // Throws
            OutputStream ostream = sftpobj.getContent().getOutputStream();

            // Copy bytes
            int len;
            byte[] buffer = new byte[1024];
            while ((len = istream.read(buffer)) != -1) {
                ostream.write(buffer, 0, len);
            }
            ostream.flush();
            ostream.close();
            istream.close();

            long size = sftpobj.getContent().getSize();
            success = sftpobj.exists() && size == ftpobj.getContent().getSize();
            System.out.println(success ? "    Successful, copied " + size + " bytes" : "    Failed");
        }
        catch (Exception e) { e.printStackTrace(); }
        if (!success) {
            System.err.println("Sorry, could not upload file, exiting");
        }
    }

    /**
     * Functionality for testing and debugging.
     * <p/>
     * Supported arguments:
     * <code>
     * -host [value]               SFTP server address
     * -username [value]           SFTP username
     * -password [value]           SFTP user password
     * -port [value]               SFTP port (optional, default: 22)
     * -path [value]               SFTP subdirectory (optional, e.g. "/home/user1")
     * </code>
     * <p/>
     * @param args Array of strings with console arguments
     * @since 1.6
     */
    public static void main (String[] args) {

        String host = null, username = null, password = null, port = null, path = null;

        try {
            // Disable annoying VFS log messages like:
            // 20.09.2013 13:48:31 org.apache.commons.vfs2.VfsLog info
            // INFO: Using "C:\DOCUME~1\User1\LOCALS~1\Temp\vfs_cache" as temporary files store.
            System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog");
            System.out.println("");

            // Parse arguments
            for (int i = 0; i < args.length; i++) {
                if (args[i].equals("-host") && (i + 1) < args.length) host = args[++i];
                else if (args[i].equals("-username") && (i + 1) < args.length) username = args[++i];
                else if (args[i].equals("-password") && (i + 1) < args.length) password = args[++i];
                else if (args[i].equals("-port") && (i + 1) < args.length) port = args[++i];
                else if (args[i].equals("-path") && (i + 1) < args.length) path = args[++i];
            }

            new ExampleVFS(host, username, password, port, path);
            System.exit(0);
        }
        catch (Exception exc) {
            try { Thread.sleep(1000); }
            catch (Exception e) { }
            exc.printStackTrace();
        }
        System.exit(1);
    }
}
