package leigh.tansu.service;

import leigh.eo.EO;
import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.nio.file.Path;
import java.util.zip.ZipFile;

/**
 * Implementation of a Tansu filesystem file for the purposes of reading.
 *
 * @author Alex Leigh
 */
// TODO Extract a generic interface here
public class TansuFileObject implements AutoCloseable {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(TansuFileObject.class);
    private final ZipFile zip;

    public TansuFileObject(Path path) throws IOException {
        zip = new ZipFile(path.toFile());
    }

    /**
     * Return an input stream for the main content of this object. This method may be called multiple times,
     * which will result in multiple input streams being returned. The caller should close the stream, but if
     * the caller does not, it will be closed when <code>close()</code> is called on this object.
     */
    public BufferedInputStream getMainInputStream() throws IOException {
        return new BufferedInputStream(zip.getInputStream(zip.getEntry(TansuFileStore.MAIN_FILENAME)));
    }

    /**
     * Return a {@link EO} representing the meta contents. This method may be called multiple times, but it will
     * read and process the meta multiple times, returning a new object each time, so that usage is discouraged.
     */
    public EO readMeta() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(
                new BufferedInputStream(zip.getInputStream(zip.getEntry(TansuFileStore.META_FILENAME))));
        return (EO) ois.readObject();
    }

    @Override
    /**
     * Close the object. This will side-effect closing all associated streams that were previously returned
     * with <code>getMainInputStream()</code>.
     */
    public void close() throws IOException {
        zip.close();
    }
}
