package com.jscape.inet.ftps;

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

import java.io.IOException;
import java.io.InputStream;

/**
 * Special InputStream implementation
 *
 * @author Alvaro
 */
public class FtpsInputStream
        extends InputStream {
    /**
     * Current Ftps instance
     */
    private Ftps ftps;

    /**
     * If it is true then allows to disconnect the ftps connection
     */
    private boolean close;

    /**
     * It is the internal InputStream
     */
    private InputStream in;

    /**
     * Creates a new FtpInputStream 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 inputstream
     * @param pos      The offset
     *
     * @throws FtpException
     * @throws IOException
     */
    public FtpsInputStream(Ftps ftps, boolean connect, boolean close,
                           String fileName, long pos)
            throws IOException, FtpException {
        this.ftps = ftps;
        if (connect) {
            this.ftps.connect();
        }
        in = ftps.getInputStream(fileName, pos);

        this.close = close;
    }

    /**
     * Method read
     * It invokes to the read method of the internal InputStream instance
     *
     * @see java.io.InputStream#read()
     */
    public int read()
            throws IOException {
        return in.read();
    }

    /**
     * Method read
     * It invokes to the read method of the internal InputStream instance
     *
     * @see java.io.InputStream#read(byte[])
     */
    public int read(byte[] b)
            throws IOException {
        return in.read(b);
    }

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

    /**
     * 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.in);

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

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

    /**
     * Method available
     * It invokes to the available method of the internal InputStream instance
     *
     * @see java.io.InputStream#available()
     */
    public synchronized int available()
            throws IOException {
        return in.available();
    }

    /**
     * Method skip
     * It invokes to the skip method of the internal InputStream instance
     *
     * @see java.io.InputStream#skip(long)
     */
    public synchronized long skip(long n)
            throws IOException {
        return in.skip(n);
    }

}

