package com.tomastc.bta500.lib.common;

import android.os.AsyncTask;
import android.os.StrictMode;
import android.util.Log;

import org.apache.commons.net.ftp.FTPClient;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.Map;

public class FtpClient {
    private String ftpServer = null;
    private String user = null;
    private String password = null;

    private static final int PORT = 21;

    public FtpClient(String ftpServer, String user, String password) {
        this.ftpServer = ftpServer;
        this.user = user;
        this.password = password;

        // permit all strict mode
//        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
//        StrictMode.setThreadPolicy(policy);
    }

    /**
     * Upload a file to a FTP server. A FTP URL is generated with the
     * following syntax:
     * ftp://user:password@host:port/filePath;type=i.
     *
     * @param fileName , Destination file name on FTP server (with optional
     *            preceding relative path, e.g. "myDir/myFile.txt").
     * @param source , Source file to upload.
     * @throws MalformedURLException, IOException on error.
     */
    public void upload( String fileName, File source ) throws MalformedURLException,
            IOException {
        if ( ftpServer != null && fileName != null && source != null)
        {
            StringBuffer sb = new StringBuffer("ftp://");
            // check for authentication else assume its anonymous access.
            if ( user != null && password != null)
            {
                sb.append(user);
                sb.append(':');
                sb.append(password);
                sb.append('@');
            }
            sb.append(ftpServer);
            sb.append('/');
            sb.append(fileName);
            /*
             * type ==&gt; a=ASCII mode, i=image (binary) mode, d= file directory
             * listing
             */
            sb.append(";type=i");

            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            try {
                URL url = new URL(sb.toString());
                URLConnection urlc = url.openConnection();

                bos = new BufferedOutputStream(urlc.getOutputStream());
                bis = new BufferedInputStream(new FileInputStream(source));

                int i;
                // read byte by byte until end of stream
                while ((i = bis.read()) != -1) {
                    bos.write(i);
                }
            } finally {
                if (bis != null)
                    try {
                        bis.close();
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    }
                if (bos != null)
                    try {
                        bos.close();
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    }
            }
        } else {
            Log.e("BTA500", "Input not available.");
        }
    }

    /**
     * Upload files to a FTP server. A FTP URL is generated with the
     * following syntax:
     * ftp://user:password@host:port/filePath;type=i.
     *
     * @param fileList, HashMap<String remote, String local(Source file to read (absolute path filename))>.
     * @throws MalformedURLException, IOException on error.
     */
    public void upload( Map<String, String> fileList ) throws MalformedURLException,
            IOException {
        FTPClient ftp = null;

        try {
            ftp = new FTPClient();
            ftp.connect(ftpServer, PORT);
            Log.d("BTA500", "Connected. Reply: " + ftp.getReplyString());

            ftp.login(user, password);
            Log.d("BTA500", "Logged in");
            ftp.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
            Log.d("BTA500", "Uploading");
            ftp.enterLocalActiveMode();

            InputStream inputStream = null;
            boolean success;
            try {
                Iterator iter = fileList.keySet().iterator();
                while (iter.hasNext()) {
                    String remote = (String) iter.next();
                    String local = (String) fileList.get(remote);

                    Log.d("BTA500", "remote file name: " + remote);
                    Log.d("BTA500", "local file name: " + local);
                    inputStream = new BufferedInputStream(new FileInputStream(local));
                    success = ftp.storeFile(remote, inputStream);
                    Log.i("SKT", success ? "uploaded" : "failed");
                }
            } catch (Exception e) {
                Log.e("BTA500", e.getMessage());
                throw e;
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
            }

        } finally {
            if (ftp != null) {
                ftp.logout();
                ftp.disconnect();
            }
        }
    }

    /**
     * Download files to a FTP server. A FTP URL is generated with the
     * following syntax:
     * ftp://user:password@host:port/filePath;type=i.
     *
     * @param fileList, HashMap<String remote, String local(Destination file to store (absolute path filename))>.
     * @throws MalformedURLException, IOException on error.
     */
    public void download( Map<String, String> fileList ) throws MalformedURLException,
            IOException {
        FTPClient ftp = null;

        try {
            ftp = new FTPClient();
            ftp.connect(ftpServer, PORT);
            Log.d("BTA500", "Connected. Reply: " + ftp.getReplyString());

            ftp.login(user, password);
            Log.d("BTA500", "Logged in");
            ftp.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
            Log.d("BTA500", "Downloading");
            ftp.enterLocalActiveMode();

            OutputStream outputStream = null;
            boolean success;
            Iterator iter = fileList.keySet().iterator();
            while (iter.hasNext()) {
                String remote = (String) iter.next();
                String local = (String) fileList.get(remote);

                Log.d("BTA500", "remote file name: " + remote);
                Log.d("BTA500", "local file name: " + local);
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(local));
                    success = ftp.retrieveFile(remote, outputStream);
                    Log.i("SKT", success ? "downloaded" : "failed");
                } catch (Exception e) {
                    Log.e("BTA500", e.getMessage());
                    throw e;
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
            }
        } catch (Exception e) {
            throw e;
        } finally {
            if (ftp != null) {
                ftp.logout();
                ftp.disconnect();
            }
        }
    }
}
