package com.ericsson.uecontrol.core.behaviour;

import com.ericsson.uecontrol.core.util.Configurator.Configurable;

import com.ericsson.uecontrol.core.util.StringUtil;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.log4j.Logger;

import java.io.*;
import java.util.regex.Pattern;

/**
 * This behaviour simulates downloading a file from FTP
 *
 * Created by ezivkoc on 2014-07-15.
 */
public class UeBehaviourFtpUpload extends UeBehaviourFtp {
    private static final Logger log = Logger.getLogger(UeBehaviourFtpUpload.class);
    private static final int BUFFER_SIZE = 512;


    @Configurable(order=1, value="Host")
    private String host;
    @Configurable(order=2, value="Remote Path")
    private String remotePath;
    @Configurable(order=3, value="Username")
    private String username;
    @Configurable(order=4, value="Password")
    private String password;
    @Configurable(order=5, value="Random data Size(Bytes) or Local File Path")
    private String sizeOrFile;


    @Override
    protected void executeFtp(FTPClient ftp) throws IOException {
        log.debug("Uploading to FTP file: " + getFtpUrl(remotePath));
        OutputStream outStream = ftp.storeFileStream(remotePath);
        if (outStream != null) {
            OutputStream out = new BufferedOutputStream(outStream);

            if(sizeOrFile != null && Pattern.matches("\\d*", sizeOrFile)){
                int size = Integer.parseInt(sizeOrFile);
                uploadRandomData(out, size);
            }
            else{
                uploadLocalFile(out, new File(sizeOrFile));
            }

            out.close();
            if(!ftp.completePendingCommand()) {
                throw new IOException("FTP reply: "+ftp.getReplyString());
            }
        } else {
            throw new IOException("FTP reply: "+ftp.getReplyString());
        }
    }

    private void uploadRandomData(OutputStream out, int size) throws IOException {
        // Upload data
        log.debug("Uploading random data with size "+size);
        int total = 0;
        byte[] data = new byte[BUFFER_SIZE];
        while (total < size && !stopExecution()) {
            int writeLength = (total + data.length < size ? data.length : size - total);
            out.write(data, 0, writeLength);

            total += writeLength;
            super.setProgress((float) total / size);
        }
    }

    private void uploadLocalFile(OutputStream out, File file) throws IOException {
        log.debug("Uploading local file "+file.getAbsolutePath());
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
        try {
            // Upload file
            int writeLength = 0;
            int total = 0;
            byte[] data = new byte[BUFFER_SIZE];
            while ((writeLength = in.read(data)) > 0 && !stopExecution()) {
                out.write(data, 0, writeLength);

                total += writeLength;
                super.setProgress((float) total / file.length());
            }
        } finally {
            in.close();
        }
    }

    @Override
    public String getHost() {
        return host;
    }
    @Override
    public String getUsername() {
        return username;
    }
    @Override
    public String getPassword() {
        return password;
    }


    @Override
    public String getName() {
        return "FTP Upload";
    }

    @Override
    public String toString() {
        if(sizeOrFile != null && Pattern.matches("\\d*", sizeOrFile)){
            int size = Integer.parseInt(sizeOrFile);
            return "Will upload "+ StringUtil.getByteString(size) +" of random data.";
        }
        return "Will upload local file "+ sizeOrFile;
    }

}
