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

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipException;

import org.apache.ant.compress.resources.ArFileSet;
import org.apache.ant.compress.resources.CommonsCompressArchiveResource;
import org.apache.ant.compress.resources.CpioFileSet;
import org.apache.ant.compress.resources.TarFileSet;
import org.apache.ant.compress.resources.TarResource;
import org.apache.ant.compress.resources.ZipFileSet;
import org.apache.ant.compress.resources.ZipResource;
import org.apache.ant.compress.util.ArchiveStreamFactory;
import org.apache.ant.compress.util.EntryHelper;
import org.apache.ant.compress.util.StreamHelper;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ExtraFieldUtils;
import org.apache.commons.compress.archivers.zip.ZipExtraField;
import org.apache.commons.compress.archivers.zip.ZipShort;
import org.apache.commons.compress.utils.IOUtils;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.types.ArchiveFileSet;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.ArchiveResource;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.MappedResource;
import org.apache.tools.ant.types.resources.Resources;
import org.apache.tools.ant.types.resources.Restrict;
import org.apache.tools.ant.types.resources.selectors.Name;
import org.apache.tools.ant.types.resources.selectors.Not;
import org.apache.tools.ant.types.resources.selectors.Or;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.IdentityMapper;
import org.apache.tools.ant.util.MergingMapper;
import org.apache.tools.ant.util.ResourceUtils;
import org.apache.tools.zip.UnixStat;

/**
 * Base implementation of tasks creating archives.
 */
public abstract class ArchiveBase extends Task {
    private ArchiveStreamFactory factory;
    private FileSetBuilder fileSetBuilder;
    private EntryBuilder entryBuilder;

    private Resource dest;
    private List/*<ResourceCollection>*/ sources = new ArrayList();
    private Mode mode = new Mode();
    private String encoding;
    private boolean filesOnly = true;
    private boolean preserve0permissions = false;
    private boolean roundUp = true;
    private boolean preserveLeadingSlashes = false;
    private Duplicate duplicate = new Duplicate();
    private WhenEmpty emptyBehavior = new WhenEmpty();

    private static final String NO_SOURCES_MSG = "No sources, nothing to do.";

    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

    protected ArchiveBase() {}

    protected final void setFactory(ArchiveStreamFactory factory) {
        this.factory = factory;
    }

    protected final ArchiveStreamFactory getFactory() {
        return factory;
    }

    protected final void setEntryBuilder(EntryBuilder builder) {
        this.entryBuilder = builder;
    }

    protected final EntryBuilder getEntryBuilder() {
        return entryBuilder;
    }

    protected final void setFileSetBuilder(FileSetBuilder builder) {
        this.fileSetBuilder = builder;
    }

    protected final FileSetBuilder getFileSetBuilder() {
        return fileSetBuilder;
    }

    /**
     * The archive to create.
     */
    public void setDestfile(File f) {
        setDest(new FileResource(f));
    }

    /**
     * The archive to create.
     */
    public void addConfiguredDest(Resources r) {
        for (Iterator it = r.iterator(); it.hasNext(); ) {
            setDest((Resource) it.next());
        }
    }

    /**
     * The archive to create.
     */
    public void setDest(Resource r) {
        if (dest != null) {
            throw new BuildException("Can only have one destination resource"
                                     + " for archive.");
        }
        dest = r;
    }

    protected Resource getDest() {
        return dest;
    }

    /**
     * Sources for the archive.
     */
    public void add(ResourceCollection c) {
        sources.add(c);
    }

    /**
     * How to treat the target archive.
     */
    public void setMode(Mode m) {
        mode = m;
    }

    protected Mode getMode() {
        return mode;
    }

    /**
     * Encoding of file names.
     */
    public void setEncoding(String e) {
        encoding = e;
    }

    /**
     * Encoding of file names.
     */
    public String getEncoding() {
        return encoding;
    }

    /**
     * Whether only file entries should be added to the archive.
     */
    public void setFilesOnly(boolean b) {
        filesOnly = b;
    }

    /**
     * Whether only file entries should be added to the archive.
     */
    protected boolean isFilesOnly() {
        return filesOnly;
    }

    /**
     * Whether 0 permissions read from an archive should be considered
     * real permissions (that should be preserved) or missing
     * permissions (which is the default).
     */
    public void setPreserve0permissions(boolean b) {
        preserve0permissions = b;
    }

    /**
     * Whether the file modification times will be rounded up to the
     * next timestamp (second or even second depending on the archive
     * format).
     *
     * <p>Zip archives store file modification times with a
     * granularity of two seconds, ar, tar and cpio use a granularity
     * of one second.  Times will either be rounded up or down.  If
     * you round down, the archive will always seem out-of-date when
     * you rerun the task, so the default is to round up.  Rounding up
     * may lead to a different type of problems like JSPs inside a web
     * archive that seem to be slightly more recent than precompiled
     * pages, rendering precompilation useless.</p>
     * @param r a <code>boolean</code> value
     */
    public void setRoundUp(boolean r) {
        roundUp = r;
    }

    /**
     * Flag to indicates whether leading `/'s should
     * be preserved in the file names.
     * Optional, default is <code>false</code>.
     * @param b the leading slashes flag.
     */
    public void setPreserveLeadingSlashes(boolean b) {
        this.preserveLeadingSlashes = b;
    }

    /**
     * Flag to indicates whether leading `/'s should
     * be preserved in the file names.
     * @since Apache Compress Antlib 1.1
     */
    public boolean getPreserveLeadingSlashes() {
        return preserveLeadingSlashes;
    }

    /**
     * Sets behavior for when a duplicate file is about to be added -
     * one of <code>add</code>, <code>preserve</code> or <code>fail</code>.
     * Possible values are: <code>add</code> (keep both
     * of the files); <code>preserve</code> (keep the first version
     * of the file found); <code>fail</code> halt a problem
     * Default is <code>fail</code>
     * @param df a <code>Duplicate</code> enumerated value
     */
    public void setDuplicate(Duplicate df) {
        duplicate = df;
    }

    /**
     * Sets behavior of the task when no resources are to be added.
     * Possible values are: <code>fail</code> (throw an exception
     * and halt the build); <code>skip</code> (do not create
     * any archive, but issue a warning);.
     * Default is <code>fail</code>;
     * @param we a <code>WhenEmpty</code> enumerated value
     */
    public void setWhenempty(WhenEmpty we) {
        emptyBehavior = we;
    }

    public void execute() {
        validate();
        final Resource targetArchive = getDest();
        if (!targetArchive.isExists()) {
            // force create mode
            mode = new Mode();
            mode.setValue(Mode.FORCE_CREATE);
        }
        Collection sourceResources;
        try {
            sourceResources = findSources();
        } catch (IOException ioex) {
            throw new BuildException("Failed to read sources", ioex);
        }
        if (sourceResources.size() == 0) {
            if (WhenEmpty.SKIP.equals(emptyBehavior.getValue())) {
                log(NO_SOURCES_MSG, Project.MSG_WARN);
            } else {
                throw new BuildException(NO_SOURCES_MSG);
            }
        } else {
            File copyOfDest = maybeCopyTarget();
            Resource destOrCopy = copyOfDest == null
                ? targetArchive
                : new FileResource(copyOfDest);
            ArchiveFileSet existingEntries =
                fileSetBuilder.buildFileSet(destOrCopy);
            existingEntries.setProject(getProject());
            try {

                List/*<ResourceWithFlags>*/ toAdd
                    = new ArrayList/*<ResourceWithFlags>*/();
                toAdd.addAll(sourceResources);

                if (checkAndLogUpToDate(toAdd, targetArchive,
                                        existingEntries)) {
                    return;
                }

                addResourcesToKeep(toAdd, existingEntries, sourceResources);
                sort(toAdd);

                try {
                    writeArchive(toAdd);
                } catch (IOException ioex) {
                    throw new BuildException("Failed to write archive", ioex);
                }
            } finally {
                if (copyOfDest != null) {
                    FILE_UTILS.tryHardToDelete(copyOfDest);
                }
            }
        }
    }

    /**
     * Argument validation.
     */
    protected void validate() throws BuildException {
        if (factory == null) {
            throw new BuildException("subclass didn't provide a factory"
                                     + " instance");
        }
        if (entryBuilder == null) {
            throw new BuildException("subclass didn't provide an entryBuilder"
                                     + " instance");
        }
        if (fileSetBuilder == null) {
            throw new BuildException("subclass didn't provide a fileSetBuilder"
                                     + " instance");
        }
        if (getDest() == null) {
            throw new BuildException("must provide a destination resource");
        }
        if (sources.size() == 0) {
            throw new BuildException("must provide sources");
        }
    }

    /**
     * Find all the resources with their flags that should be added to
     * the archive.
     */
    protected Collection/*<ResourceWithFlags>*/ findSources()
        throws IOException {

        List/*<ResourceWithFlags>*/ l = new ArrayList/*<ResourceWithFlags>*/();
        Set/*<String>*/ addedNames = new HashSet/*<String>*/();
        for (Iterator rcs = sources.iterator(); rcs.hasNext(); ) {
            ResourceCollection rc = (ResourceCollection) rcs.next();
            ResourceCollectionFlags rcFlags = getFlags(rc);
            for (Iterator rs = rc.iterator(); rs.hasNext(); ) {
                Resource r = (Resource) rs.next();
                if (!isFilesOnly() || !r.isDirectory()) {
                    ResourceWithFlags rwf =
                        new ResourceWithFlags(r, rcFlags, getFlags(r));
                    String name = rwf.getName();
                    if (!"".equals(name) && !"/".equals(name)) {
                        boolean isDup = !addedNames.add(name);
                        if (!isDup || addDuplicate(name)) {
                            l.add(rwf);
                        }
                    }
                }
            }
        }
        return l;
    }

    private boolean checkAndLogUpToDate(Collection/*<ResourceWithFlags>*/ src,
                                        Resource targetArchive,
                                        ArchiveFileSet existingEntries) {
        try {
            if (!Mode.FORCE_CREATE.equals(getMode().getValue())
                && !Mode.FORCE_REPLACE.equals(getMode().getValue())
                && isUpToDate(src, existingEntries)) {
                log(targetArchive + " is up-to-date, nothing to do.");
                return true;
            }
        } catch (IOException ioex) {
            throw new BuildException("Failed to read target archive", ioex);
        }
        return false;
    }

    /**
     * Checks whether the target is more recent than the resources
     * that shall be added to it.
     *
     * <p>Will only ever be invoked if the target exists.</p>
     *
     * @param src the resources that have been found as sources, may
     * be modified in "update" mode to remove entries that are up to
     * date
     * @param existingEntries the target archive as fileset
     *
     * @return true if the target is up-to-date
     */
    protected boolean isUpToDate(Collection/*<ResourceWithFlags>*/ src,
                                 ArchiveFileSet existingEntries)
        throws IOException {

        final Resource[] srcResources = new Resource[src.size()];
        int index = 0;
        for (Iterator i = src.iterator(); i.hasNext(); ) {
            ResourceWithFlags r = (ResourceWithFlags) i.next();
            srcResources[index++] =
                new MappedResource(r.getResource(),
                                   new MergingMapper(r.getName()));
        }
        Resource[] outOfDate = ResourceUtils
            .selectOutOfDateSources(this, srcResources,
                                    new IdentityMapper(),
                                    existingEntries
                                    .getDirectoryScanner(getProject()));
        if (outOfDate.length > 0 && Mode.UPDATE.equals(getMode().getValue())) {
            HashSet/*<String>*/ oodNames = new HashSet/*<String>*/();
            for (int i = 0; i < outOfDate.length; i++) {
                oodNames.add(outOfDate[i].getName());
            }
            List/*<ResourceWithFlags>*/ copy =
                new LinkedList/*<ResourceWithFlags>*/(src);
            src.clear();
            for (Iterator i = copy.iterator(); i.hasNext(); ) {
                ResourceWithFlags r = (ResourceWithFlags) i.next();
                if (oodNames.contains(r.getName())) {
                    src.add(r);
                }
            }
        }
        return outOfDate.length == 0;
    }

    /**
     * Add the resources of the target archive that shall be kept when
     * creating the new one.
     */
    private void addResourcesToKeep(Collection/*<ResourceWithFlags>*/ toAdd,
                                    ArchiveFileSet target,
                                    Collection/*<ResourceWithFlags>*/ src) {
        if (!Mode.FORCE_CREATE.equals(getMode().getValue())
            && !Mode.CREATE.equals(getMode().getValue())) {
            try {
                toAdd.addAll(findUnmatchedTargets(target, src));
            } catch (IOException ioex) {
                throw new BuildException("Failed to read target archive", ioex);
            }
        }
    }

    /**
     * Find the resources from the target archive that don't have a
     * matching resource in the sources to be added.
     */
    protected Collection/*<ResourceWithFlags>*/
        findUnmatchedTargets(ArchiveFileSet target,
                             Collection/*<ResourceWithFlags>*/ src)
        throws IOException {

        List/*<ResourceWithFlags>*/ l = new ArrayList/*<ResourceWithFlags>*/();
        ResourceCollectionFlags rcFlags = getFlags(target);

        Restrict res = new Restrict();
        res.setProject(getProject());
        res.add(target);

        Not not = new Not();
        Or or = new Or();
        not.add(or);
        for (Iterator i = src.iterator(); i.hasNext(); ) {
            ResourceWithFlags r = (ResourceWithFlags) i.next();
            Name name = new Name();
            name.setName(r.getName());
            or.add(name);
        }
        res.add(not);

        for (Iterator rs = res.iterator(); rs.hasNext(); ) {
            Resource r = (Resource) rs.next();
            String name = r.getName();
            if ("".equals(name) || "/".equals(name)) {
                continue;
            }
            if (!isFilesOnly() || !r.isDirectory()) {
                l.add(new ResourceWithFlags(r, rcFlags, getFlags(r)));
            }
        }

        return l;
    }

    /**
     * Sorts the list of resources to add.
     */
    protected void sort(List/*<ResourceWithFlags>*/ l) {
        Collections.sort(l, new Comparator/*<ResourceWithFlags>*/() {
                public int compare(Object o1, Object o2) {
                    ResourceWithFlags r1 = (ResourceWithFlags) o1;
                    ResourceWithFlags r2 = (ResourceWithFlags) o2;
                    return r1.getName().compareTo(r2.getName());
                }
            });
    }

    /**
     * Creates the archive archiving the given resources.
     */
    protected void writeArchive(Collection/*<ResourceWithFlags>*/ src)
        throws IOException {
        ArchiveOutputStream out = null;
        Set addedDirectories = new HashSet();
        try {
            String enc = Expand.NATIVE_ENCODING.equals(getEncoding())
                ? null : getEncoding();
            out = StreamHelper.getOutputStream(factory, getDest(), enc);
            if (out == null) {
                out =
                    factory.getArchiveStream(new BufferedOutputStream(getDest()
                                                                      .getOutputStream()),
                                             enc);
            }
            for (Iterator i = src.iterator(); i.hasNext(); ) {
                ResourceWithFlags r = (ResourceWithFlags) i.next();

                if (!isFilesOnly()) {
                    ensureParentDirs(out, r, addedDirectories);
                }

                ArchiveEntry ent = entryBuilder.buildEntry(r);
                out.putArchiveEntry(ent);
                if (!r.getResource().isDirectory()) {
                    InputStream in = null;
                    try {
                        in = r.getResource().getInputStream();
                        IOUtils.copy(in, out);
                    } finally {
                        FILE_UTILS.close(in);
                    }
                } else {
                    addedDirectories.add(r.getName());
                }
                out.closeArchiveEntry();

            }
        } finally {
            FILE_UTILS.close(out);
        }
    }

    /**
     * Adds records for all parent directories of the given resource
     * that haven't already been added.
     *
     * <p>Flags for the "missing" directories will be taken from the
     * ResourceCollection that contains the resource to be added.</p>
     */
    protected void ensureParentDirs(ArchiveOutputStream out,
                                    ResourceWithFlags r,
                                    Set directoriesAdded)
        throws IOException {

        String[] parentStack = FileUtils.getPathStack(r.getName());
        String currentParent = "";
        int skip = r.getName().endsWith("/") ? 2 : 1;
        for (int i = 0; i < parentStack.length - skip; i++) {
            if ("".equals(parentStack[i])) continue;
            currentParent += parentStack[i] + "/";
            if (directoriesAdded.add(currentParent)) {
                Resource dir = new Resource(currentParent, true,
                                            System.currentTimeMillis(),
                                            true);
                ResourceWithFlags artifical =
                    new ResourceWithFlags(currentParent,
                                          dir, r.getCollectionFlags(),
                                          new ResourceFlags());
                ArchiveEntry ent = entryBuilder.buildEntry(artifical);
                out.putArchiveEntry(ent);
                out.closeArchiveEntry();
            }
        }
    }

    /**
     * Extracts flags from a resource.
     *
     * <p>ZipExceptions are only here for the code that translates
     * Ant's ZipExtraFields to CC ZipExtraFields and should never
     * actually be thrown.</p>
     */
    protected ResourceFlags getFlags(Resource r) throws ZipException {
        if (r instanceof ArchiveResource) {
            if (r instanceof CommonsCompressArchiveResource) {
                if (r instanceof TarResource) {
                    TarResource tr = (TarResource) r;
                    return new ResourceFlags(tr.getMode(), tr.getUid(),
                                             tr.getGid(), tr.getUserName(),
                                             tr.getGroup());
                } else if (r instanceof ZipResource) {
                    ZipResource zr = (ZipResource) r;
                    return new ResourceFlags(zr.getMode(), zr.getExtraFields(),
                                             zr.getMethod());
                } else {
                    CommonsCompressArchiveResource cr =
                        (CommonsCompressArchiveResource) r;
                    return new ResourceFlags(cr.getMode(), cr.getUid(),
                                             cr.getGid());
                }
            } else if (r instanceof
                       org.apache.tools.ant.types.resources.TarResource) {
                org.apache.tools.ant.types.resources.TarResource tr =
                    (org.apache.tools.ant.types.resources.TarResource) r;
                return new ResourceFlags(tr.getMode(), tr.getUid(),
                                         tr.getGid(), tr.getUserName(),
                                         tr.getGroup());
            } else if (r instanceof
                       org.apache.tools.ant.types.resources.ZipResource) {
                org.apache.tools.ant.types.resources.ZipResource zr =
                    (org.apache.tools.ant.types.resources.ZipResource) r;

                org.apache.tools.zip.ZipExtraField[] extra = zr.getExtraFields();
                ZipExtraField[] ex =
                    new ZipExtraField[extra == null ? 0 : extra.length];
                if (extra != null && extra.length > 0) {
                    for (int i = 0; i < extra.length; i++) {
                        try {
                            ex[i] = ExtraFieldUtils
                                .createExtraField(new ZipShort(extra[i]
                                                               .getHeaderId()
                                                               .getValue()));
                        } catch (InstantiationException e) {
                            throw new BuildException(e);
                        } catch (IllegalAccessException e) {
                            throw new BuildException(e);
                        }
                        byte[] b = extra[i].getCentralDirectoryData();
                        ex[i].parseFromCentralDirectoryData(b, 0, b.length);
                        b = extra[i].getLocalFileDataData();
                        ex[i].parseFromLocalFileData(b, 0, b.length);
                    }
                }

                return new ResourceFlags(zr.getMode(), ex, zr.getMethod());
            } else {
                ArchiveResource ar = (ArchiveResource) r;
                return new ResourceFlags(ar.getMode());
            }
        }
        return new ResourceFlags();
    }

    /**
     * Extracts flags from a resource collection.
     */
    protected ResourceCollectionFlags getFlags(ResourceCollection rc) {
        if (rc instanceof ArchiveFileSet) {
            if (rc instanceof ArFileSet) {
                ArFileSet ar = (ArFileSet) rc;
                return new ResourceCollectionFlags(ar.getPrefix(getProject()),
                                                   ar.getFullpath(getProject()),
                                                   ar.hasFileModeBeenSet()
                                                   ? ar.getFileMode(getProject())
                                                   : -1,
                                                   ar.hasDirModeBeenSet()
                                                   ? ar.getDirMode(getProject())
                                                   : -1,
                                                   ar.hasUserIdBeenSet()
                                                   ? ar.getUid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   ar.hasGroupIdBeenSet()
                                                   ? ar.getGid()
                                                   : EntryHelper.UNKNOWN_ID);
            } else if (rc instanceof CpioFileSet) {
                CpioFileSet cr = (CpioFileSet) rc;
                return new ResourceCollectionFlags(cr.getPrefix(getProject()),
                                                   cr.getFullpath(getProject()),
                                                   cr.hasFileModeBeenSet()
                                                   ? cr.getFileMode(getProject())
                                                   : -1,
                                                   cr.hasDirModeBeenSet()
                                                   ? cr.getDirMode(getProject())
                                                   : -1,
                                                   cr.hasUserIdBeenSet()
                                                   ? cr.getUid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   cr.hasGroupIdBeenSet()
                                                   ? cr.getGid()
                                                   : EntryHelper.UNKNOWN_ID);
            } else if (rc instanceof TarFileSet) {
                TarFileSet tr = (TarFileSet) rc;
                return new ResourceCollectionFlags(tr.getPrefix(getProject()),
                                                   tr.getFullpath(getProject()),
                                                   tr.hasFileModeBeenSet()
                                                   ? tr.getFileMode(getProject())
                                                   : -1,
                                                   tr.hasDirModeBeenSet()
                                                   ? tr.getDirMode(getProject())
                                                   : -1,
                                                   tr.hasUserIdBeenSet()
                                                   ? tr.getUid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   tr.hasGroupIdBeenSet()
                                                   ? tr.getGid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   tr.hasUserNameBeenSet()
                                                   ? tr.getUserName() : null,
                                                   tr.hasGroupBeenSet()
                                                   ? tr.getGroup() : null);
            } else if (rc instanceof
                       org.apache.tools.ant.types.TarFileSet) {
                org.apache.tools.ant.types.TarFileSet tr =
                    (org.apache.tools.ant.types.TarFileSet) rc;
                return new ResourceCollectionFlags(tr.getPrefix(getProject()),
                                                   tr.getFullpath(getProject()),
                                                   tr.hasFileModeBeenSet()
                                                   ? tr.getFileMode(getProject())
                                                   : -1,
                                                   tr.hasDirModeBeenSet()
                                                   ? tr.getDirMode(getProject())
                                                   : -1,
                                                   tr.hasUserIdBeenSet()
                                                   ? tr.getUid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   tr.hasGroupIdBeenSet()
                                                   ? tr.getGid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   tr.hasUserNameBeenSet()
                                                   ? tr.getUserName() : null,
                                                   tr.hasGroupBeenSet()
                                                   ? tr.getGroup() : null);
            } else {
                ArchiveFileSet ar = (ArchiveFileSet) rc;
                return new ResourceCollectionFlags(ar.getPrefix(getProject()),
                                                   ar.getFullpath(getProject()),
                                                   ar.hasFileModeBeenSet()
                                                   ? ar.getFileMode(getProject())
                                                   : -1,
                                                   ar.hasDirModeBeenSet()
                                                   ? ar.getDirMode(getProject())
                                                   : -1);
            }
        }
        return new ResourceCollectionFlags();
    }

    /**
     * Ensures a forward slash is used as file separator and strips
     * leading slashes if preserveLeadingSlashes is false.
     */
    protected String bendSlashesForward(String s) {
        if (s != null) {
            s = s.replace('\\', '/');
            if (File.separatorChar != '/' && File.separatorChar != '\\') { 
                s = s.replace(File.separatorChar, '/');
            }
            while (!preserveLeadingSlashes && s.startsWith("/")) {
                s = s.substring(1);
            }
        }
        return s;
    }

    /**
     * Modify last modified timestamp based on the roundup attribute.
     *
     * @param millis the timestamp
     * @param granularity the granularity of timestamps in the archive
     * format in millis
     */
    protected long round(long millis, long granularity) {
        return roundUp ? millis + granularity - 1 : millis;
    }

    /**
     * Is invoked if a duplicate entry is found, decides whether the
     * entry shall be added regardless.
     */
    protected boolean addDuplicate(String name) {
        if (duplicate.getValue().equals(Duplicate.PRESERVE)) {
            log(name + " already added, skipping.", Project.MSG_INFO);
            return false;
        } else if (duplicate.getValue().equals(Duplicate.FAIL)) {
            throw new BuildException("Duplicate entry " + name
                                     + " was found and the duplicate "
                                     + "attribute is 'fail'.");
        }
        // duplicate equal to add, so we continue
        log("duplicate entry " + name + " found, adding.", Project.MSG_VERBOSE);
        return true;
    }

    /**
     * Creates a copy of the target archive in update or recreate mode
     * because some entries may later be read and archived from it.
     */
    private File maybeCopyTarget() {
        File copyOfDest = null;
        try {
            if (!Mode.FORCE_CREATE.equals(getMode().getValue())
                && !Mode.CREATE.equals(getMode().getValue())) {
                copyOfDest = FILE_UTILS.createTempFile(getTaskName(), ".tmp",
                                                       null, true, false);
                ResourceUtils.copyResource(getDest(),
                                           new FileResource(copyOfDest));
            }
        } catch (IOException ioex) {
            if (copyOfDest != null && copyOfDest.exists()) {
                FILE_UTILS.tryHardToDelete(copyOfDest);
            }
            throw new BuildException("Failed to copy target archive", ioex);
        }
        return copyOfDest;
    }

    /**
     * Valid Modes for create/update/replace.
     */
    public static final class Mode extends EnumeratedAttribute {

        /**
         * Create a new archive.
         */
        public static final String CREATE = "create";
        /**
         * Create a new archive even if the target exists and seems
         * up-to-date.
         */
        public static final String FORCE_CREATE = "force-create";
        /**
         * Update an existing archive.
         */
        public static final String UPDATE = "update";
        /**
         * Update an existing archive, replacing all existing entries
         * with those from sources.
         */
        public static final String REPLACE = "replace";
        /**
         * Update an existing archive - replacing all existing entries
         * with those from sources - even if the target exists and
         * seems up-to-date.
         */
        public static final String FORCE_REPLACE = "force-replace";

        public Mode() {
            super();
            setValue(CREATE);
        }

        public String[] getValues() {
            return new String[] {CREATE, UPDATE, REPLACE,
                                 FORCE_CREATE, FORCE_REPLACE};
        }

    }

    /**
     * Possible behaviors when a duplicate file is added:
     * "add", "preserve" or "fail"
     */
    public static class Duplicate extends EnumeratedAttribute {
        private static String ADD = "add";
        private static String PRESERVE = "preserve";
        private static String FAIL = "fail";

        public Duplicate() {
            setValue(FAIL);
        }

        /**
         * @see EnumeratedAttribute#getValues()
         */
        /** {@inheritDoc} */
        public String[] getValues() {
            return new String[] {ADD, PRESERVE, FAIL};
        }
    }

    /**
     * Possible behaviors when there are no matching files for the task:
     * "fail", "skip".
     */
    public static class WhenEmpty extends EnumeratedAttribute {
        private static String FAIL = "fail";
        private static String SKIP = "skip";

        public WhenEmpty() {
            setValue(FAIL);
        }

        /**
         * The string values for the enumerated value
         * @return the values
         */
        public String[] getValues() {
            return new String[] {FAIL, SKIP};
        }
    }

    /**
     * Various flags a (archive) resource may hold in addition to
     * being a plain resource.
     */
    // FIXME this isn't really scaling if it wants to be a catch all
    // for all relevant flags of all formats.
    public class ResourceFlags {
        private final int mode;
        private final boolean modeSet;
        private final int gid;
        private final int uid;
        private final ZipExtraField[] extraFields;
        private final String userName;
        private final String groupName;
        private final int compressionMethod;
        private Iterable/*<? extends SevenZMethodConfiguration>*/ contentMethods;

        public ResourceFlags() {
            this(-1);
        }

        public ResourceFlags(int mode) {
            this(mode, new ZipExtraField[0], -1);
        }

        public ResourceFlags(int mode, ZipExtraField[] extraFields,
                             int compressionMethod) {
            this(mode, extraFields, EntryHelper.UNKNOWN_ID,
                 EntryHelper.UNKNOWN_ID, null, null,
                 compressionMethod, null);
        }

        public ResourceFlags(int mode, int uid, int gid) {
            this(mode, new ZipExtraField[0], uid, gid, null, null, -1, null);
        }

        public ResourceFlags(int mode, int uid, int gid, String userName,
                             String groupName) {
            this(mode, new ZipExtraField[0], uid, gid, userName, groupName, -1, null);
        }

        public ResourceFlags(Iterable/*<? extends SevenZMethodConfiguration>*/ contentMethods) {
            this(-1, new ZipExtraField[0], EntryHelper.UNKNOWN_ID,
                 EntryHelper.UNKNOWN_ID, null, null, -1, contentMethods);
        }

        private ResourceFlags(int mode, ZipExtraField[] extraFields,
                              int uid, int gid,
                              String userName, String groupName,
                              int compressionMethod,
                              Iterable/*<? extends SevenZMethodConfiguration>*/ contentMethods) {
            this.mode = mode;
            this.extraFields = extraFields;
            this.gid = gid;
            this.uid = uid;
            this.userName = userName;
            this.groupName = groupName;
            int m = mode & UnixStat.PERM_MASK;
            modeSet = mode >= 0 && (m > 0 || (m == 0 && preserve0permissions));
            this.compressionMethod = compressionMethod;
            this.contentMethods = contentMethods;
        }

        public boolean hasModeBeenSet() { return modeSet; }
        public int getMode() { return mode; }

        public ZipExtraField[] getZipExtraFields() { return extraFields; }

        public boolean hasUserIdBeenSet() {
            return uid != EntryHelper.UNKNOWN_ID;
        }
        public int getUserId() { return uid; }

        public boolean hasGroupIdBeenSet() {
            return gid != EntryHelper.UNKNOWN_ID;
        }
        public int getGroupId() { return gid; }

        public boolean hasUserNameBeenSet() { return userName != null; }
        public String getUserName() { return userName; }

        public boolean hasGroupNameBeenSet() { return groupName != null; }
        public String getGroupName() { return groupName; }

        public boolean hasCompressionMethod() { return compressionMethod >= 0; }
        public int getCompressionMethod() { return compressionMethod; }

        public boolean hasContentMethods() { return contentMethods != null; }
        public Iterable/*<? extends SevenZMethodConfiguration>*/ getContentMethods() {
            return contentMethods;
        }
    }

    /**
     * Various flags a (archive) resource collection may hold.
     */
    public class ResourceCollectionFlags extends ResourceFlags {
        private final String prefix, fullpath;
        private final int dirMode;

        public ResourceCollectionFlags() {
            this(null, null);
        }

        public ResourceCollectionFlags(String prefix, String fullpath) {
            this(prefix, fullpath, -1, -1);
        }

        public ResourceCollectionFlags(String prefix, String fullpath,
                                       int fileMode, int dirMode) {
            this(prefix, fullpath, fileMode, dirMode, EntryHelper.UNKNOWN_ID,
                 EntryHelper.UNKNOWN_ID);
        }

        public ResourceCollectionFlags(String prefix, String fullpath,
                                       int fileMode, int dirMode,
                                       int uid, int gid) {
            this(prefix, fullpath, fileMode, dirMode, uid, gid, null, null);
        }

        public ResourceCollectionFlags(String prefix, String fullpath,
                                       int fileMode, int dirMode,
                                       int uid, int gid,
                                       String userName, String groupName) {
            super(fileMode, uid, gid, userName, groupName);
            this.dirMode = dirMode;
            this.prefix = bendSlashesForward(prefix);
            this.fullpath = bendSlashesForward(fullpath);
        }

        public boolean hasDirModeBeenSet() { return dirMode >= 0; }
        public int getDirMode() { return dirMode; }

        public boolean hasPrefix() {
            return prefix != null && !"".equals(prefix);
        }
        public String getPrefix() { return prefix; }

        public boolean hasFullpath() {
            return fullpath != null && !"".equals(fullpath);
        }
        public String getFullpath() { return fullpath; }
    }

    /**
     * Binds a resource to additional data that may be present.
     */
    public class ResourceWithFlags {
        private final Resource r;
        private final ResourceCollectionFlags rcFlags;
        private final ResourceFlags rFlags;
        private final String name;

        public ResourceWithFlags(Resource r, ResourceCollectionFlags rcFlags,
                                 ResourceFlags rFlags) {
            this(null, r, rcFlags, rFlags);
        }

        public ResourceWithFlags(String name, Resource r,
                                 ResourceCollectionFlags rcFlags,
                                 ResourceFlags rFlags) {
            this.r = r;
            this.rcFlags = rcFlags;
            this.rFlags = rFlags;

            if (name == null) {
                name = r.getName();
                if (rcFlags.hasFullpath()) {
                    name = rcFlags.getFullpath();
                } else if (rcFlags.hasPrefix()) {
                    String prefix = rcFlags.getPrefix();
                    if (!prefix.endsWith("/")) {
                        prefix = prefix + "/";
                    }
                    name = prefix + name;
                }
                name = bendSlashesForward(name);
            }
            if (r.isDirectory() && !name.endsWith("/")) {
                name += "/";
            } else if (!r.isDirectory() && name.endsWith("/")) {
                name = name.substring(0, name.length() - 1);
            }

            this.name = name;
        }

        public Resource getResource() { return r; }
        public ResourceCollectionFlags getCollectionFlags() { return rcFlags; }
        public ResourceFlags getResourceFlags() { return rFlags; }

        /**
         * The name the target entry will have.
         *
         * <p>Already takes fullpath and prefix into account.</p>
         *
         * <p>Ensures directory names end in slashes while file names
         * never will.</p>
         */
        public String getName() {
            return name;
        }
    }

    /**
     * Creates an archive entry for the concrete format.
     */
    public static interface EntryBuilder {
        ArchiveEntry buildEntry(ResourceWithFlags resource);
    }

    /**
     * Creates an archive fileset to read the target archive.
     */
    public static interface FileSetBuilder {
        ArchiveFileSet buildFileSet(Resource dest);
    }
}
