package com.jscape.inet.ftps;

import com.jscape.inet.ftp.FtpException;
import com.jscape.util.IOTools;

import java.io.IOException;
import java.io.OutputStream;

/**
 * Special OutputStream implementation
 *
 * @author Alvaro
 */
public class FtpsOutputStream
        extends OutputStream {
    /**
     * It is the internal OutputStream
     */
    private OutputStream out;
    /**
     * If it is true then allows to disconnect the ftps connection
     */
    private boolean close;
    /**
     * Current Ftps instance
     */
    private Ftps ftps;

    /**
     * Creates a new FtpOutputStream instance and keeps the ftps connection open
     *
     * @param ftps     Current ftps instance
     * @param connect  <code>true</code> to establish a ftps connection,
     *                 <code>false</code> otherwise
     * @param close    <code>true</code> to disconnect the ftps connection,
     *                 <code>false</code> otherwise
     * @param fileName The file name which is going to be used to create the ouputstream
     * @param pos      The offset
     * @param append   It is the append flag
     *
     * @throws FtpException
     * @throws IOException
     */
    public FtpsOutputStream(Ftps ftps, boolean connect, boolean close,
                            String fileName, long pos, boolean append)
            throws FtpException, IOException {

        this.ftps = ftps;
        this.close = close;
        if (connect) {
            this.ftps.connect();
        }
        out = ftps.getOutputStream(fileName, pos, append);
    }

    /**
     * Method close
     * If close is true then it disconnect the ftps connection,
     * and reads the last response from the server
     *
     * @see java.io.OutputStream#close()
     */
    public void close()
            throws IOException {
        IOTools.close(this.out);

        try {
            this.ftps.readResponse();
        } catch (FtpException e) {
            // ignore
        }

        if (this.close) {
            this.ftps.disconnect();
        }
    }

    /**
     * Method flush
     * It invokes to the flush method of the internal OutputStream instance
     *
     * @see java.io.OutputStream#flush()
     */
    public void flush()
            throws IOException {
        out.flush();
    }

    /**
     * Method write
     * It invokes to the write method of the internal OutputStream instance
     *
     * @see java.io.OutputStream#write(byte[])
     */
    public void write(byte[] b)
            throws IOException {
        out.write(b);
    }

    /**
     * Method write
     * It invokes to the write method of the internal OutputStream instance
     *
     * @see java.io.OutputStream#write(byte[], int, int)
     */
    public void write(byte[] b, int off, int len)
            throws IOException {
        out.write(b, off, len);
    }

    /**
     * Method write
     * It invokes to the write method of the internal OutputStream instance
     *
     * @see java.io.OutputStream#write(int)
     */
    public void write(int b)
            throws IOException {
        out.write(b);
    }

}
