/*
 *  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;
    }

    @Override
    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);
    }
}
