/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package org.apache.ant.compress.resources;

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

import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.resources.FileProvider;
import org.apache.tools.ant.util.FileUtils;

import org.apache.ant.compress.util.SevenZStreamFactory;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;

/**
 * A Resource representation of an entry in a sevenzfile.
 *
 * @since Apache Compress Antlib 1.3
 */
public final class SevenZResource extends CommonsCompressArchiveResource {

    /**
     * Default constructor.
     */
    public SevenZResource() {
        super(new SevenZStreamFactory(), "7z");
    }

    /**
     * Construct a SevenZResource representing the specified
     * entry in the specified 7z file.
     * @param z the 7z file as File.
     * @param enc the encoding used for filenames - ignored.
     * @param e the SevenZEntry.
     */
    public SevenZResource(File z, String enc, SevenZArchiveEntry e) {
        super(new SevenZStreamFactory(), "7z", z, e);
        setEntry(e);
    }

    /**
     * Construct a SevenZResource representing the specified
     * entry in the specified 7z archive.
     * @param z the 7z archive
     * @param enc the encoding used for filenames - ignored.
     * @param e the SevenZEntry.
     */
    public SevenZResource(Resource z, String enc, SevenZArchiveEntry e) {
        super(new SevenZStreamFactory(), "sevenz", z, e);
        setEntry(e);
    }

    /**
     * Set the 7z that holds this SevenZResource.
     * @param z the 7z file as a File.
     */
    public void setSevenZFile(File z) {
        setArchive(z);
    }

    /**
     * Set the 7z file that holds this SevenZResource.
     * @param z the 7z as a Resource.
     */
    public void setSevenZResource(Resource z) {
        addConfigured(z);
    }

    /**
     * Get the 7z file that holds this SevenZResource.
     * @return the 7z file as a File or null if it is not a file.
     */
    public File getSevenZFile() {
        FileProvider fp = (FileProvider) getArchive().as(FileProvider.class);
        return fp != null ? fp.getFile() : null;
    }

    /**
     * Return an InputStream for reading the contents of this Resource.
     * @return an InputStream object.
     * @throws IOException if the sevenz file cannot be opened,
     *         or the entry cannot be read.
     */
    public InputStream getInputStream() throws IOException {
        if (isReference()) {
            return ((Resource) getCheckedRef()).getInputStream();
        }
        File f = getSevenZFile();
        if (f == null) {
            return super.getInputStream();
        }

        final SevenZFile z = new SevenZFile(f);
        SevenZArchiveEntry ze = z.getNextEntry();
        while (ze != null) {
            if (ze.getName().equals(getName())) {
                return new InputStream() {
                    public int read() throws IOException {
                        return z.read();
                    }
                    public int read(byte[] b) throws IOException {
                        return z.read(b);
                    }
                    public void close() throws IOException {
                        z.close();
                    }
                    protected void finalize() throws Throwable {
                        try {
                            close();
                        } finally {
                            super.finalize();
                        }
                    }
                };
            }
            ze = z.getNextEntry();
        }
        z.close();
        throw new BuildException("no entry " + getName() + " in "
                                 + getArchive());
    }

    /**
     * fetches information from the named entry inside the archive.
     */
    protected void fetchEntry() {
        File f = getSevenZFile();
        if (f == null) {
            super.fetchEntry();
            return;
        }

        SevenZFile z = null;
        try {
            z = new SevenZFile(f);
            SevenZArchiveEntry ze = z.getNextEntry();
            while (ze != null) {
                if (ze.getName().equals(getName())) {
                    setEntry(ze);
                    return;
                }
                ze = z.getNextEntry();
            }
            setEntry(null);
        } catch (IOException e) {
            log(e.getMessage(), Project.MSG_DEBUG);
            throw new BuildException(e);
        } finally {
            if (z != null) {
                try {
                    z.close();
                } catch (IOException ex) {
                    // swallow
                }
            }
        }
    }

}
