package network;

import main.RepositoryAdministrator;
import main.ConfigurationReader;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import org.apache.log4j.Logger;

/**
 * This class enables upload of file during recovery process in separate thread
 * 
 * @author Marcel Duris
 */
public class UploadServer extends Thread {

    private InputStream in;
    private OutputStream out;
    private Socket socket;

    /**
     * Constructor opens input stream and starts pushing bytes into socket
     * output stream.
     * 
     * @param filename stored in local repository to be uploaded.
     * @param socket Socket of connection into which file should be uploaded
     */
    public UploadServer(String filename, Socket socket) {
        try {
            String folder = ConfigurationReader.getCfg().getRepositoryFolderPath();
            String filepath = folder + "/" + filename;
            in = new BufferedInputStream(new FileInputStream(filepath));
            in = RepositoryAdministrator.getInputStream(filename);

            out = socket.getOutputStream();

            this.socket = socket;
            start();
        } catch (IOException ex) {
            Logger.getLogger("qbackup").error(ex.getMessage());
        }
    }

    /**
     * This method starts parallel upload.
     */
    @Override
    public void run() {
        pushToSocket(in, out);
    }

    /**
     * Main method pushing file into socket.
     *
     * @param in input stream
     * @param out outputstream
     */
    private void pushToSocket(InputStream in, OutputStream out) {
        Logger.getLogger("qbackup").info("Uploading file.");
        byte[] buff = new byte[1024];
        int r;
        try {
            while ((r = in.read(buff)) > 0) {
                out.write(buff, 0, r);
            }
        } catch (IOException ex) {
            Logger.getLogger("qbackup").error(ex.getMessage());
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                Logger.getLogger("qbackup").error(ex.getMessage());
            }
            try {
                in.close();
            } catch (IOException ex) {
                Logger.getLogger("qbackup").error(ex.getMessage());
            }
            try {
                socket.close();
            } catch (IOException ex) {
                Logger.getLogger("qbackup").error(ex.getMessage());
            }
        }

    }
}
