/*
 *  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.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.ArchiveFileSet;
import org.apache.tools.ant.types.DataType;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.Union;
import org.apache.tools.ant.util.CollectionUtils;

/**
 * A resource collection that treats all nested resources as archives
 * and returns the contents of the archives as its content.
 */
public class Archives extends DataType
    implements ResourceCollection, Cloneable {

    private Union zips = new Union();
    private Union tars = new Union();
    private Union ars = new Union();
    private Union cpios = new Union();

    /**
     * Wrapper to identify nested resource collections as ZIP
     * archives.
     */
    public Union createZips() {
        if (isReference()) {
            throw noChildrenAllowed();
        }
        setChecked(false);
        return zips;
    }

    /**
     * Wrapper to identify nested resource collections as ZIP
     * archives.
     */
    public Union createTars() {
        if (isReference()) {
            throw noChildrenAllowed();
        }
        setChecked(false);
        return tars;
    }

    /**
     * Wrapper to identify nested resource collections as AR
     * archives.
     */
    public Union createArs() {
        if (isReference()) {
            throw noChildrenAllowed();
        }
        setChecked(false);
        return ars;
    }

    /**
     * Wrapper to identify nested resource collections as CPIO
     * archives.
     */
    public Union createCpios() {
        if (isReference()) {
            throw noChildrenAllowed();
        }
        setChecked(false);
        return cpios;
    }

    /**
     * Sums the sizes of nested archives.
     */
    public int size() {
        if (isReference()) {
            return ((Archives) getCheckedRef()).size();
        }
        dieOnCircularReference();
        int total = 0;
        for (Iterator i = grabArchives(); i.hasNext(); ) {
            total += ((ResourceCollection) i.next()).size();
        }
        return total;
    }

    /**
     * Merges the nested collections.
     */
    public Iterator iterator() {
        if (isReference()) {
            return ((Archives) getCheckedRef()).iterator();
        }
        dieOnCircularReference();
        List l = new LinkedList();
        for (Iterator i = grabArchives(); i.hasNext(); ) {
            l.addAll(CollectionUtils
                     .asCollection(((ResourceCollection) i.next()).iterator()));
        }
        return l.iterator();
    }

    /**
     * @return false
     */
    public boolean isFilesystemOnly() {
        if (isReference()) {
            return ((Archives) getCheckedRef()).isFilesystemOnly();
        }
        dieOnCircularReference();
        return false;
    }

    /**
     * Overrides the base version.
     * @param r the Reference to set.
     */
    public void setRefid(Reference r) {
        if (zips.getResourceCollections().size() > 0
            || ars.getResourceCollections().size() > 0
            || cpios.getResourceCollections().size() > 0
            || tars.getResourceCollections().size() > 0) {
            throw tooManyAttributes();
        }
        super.setRefid(r);
    }

    /**
     * Implement clone.  The nested resource collections are cloned as
     * well.
     * @return a cloned instance.
     */
    public Object clone() {
        try {
            Archives a = (Archives) super.clone();
            a.zips = (Union) zips.clone();
            a.tars = (Union) tars.clone();
            a.ars = (Union) ars.clone();
            a.cpios = (Union) cpios.clone();
            return a;
        } catch (CloneNotSupportedException e) {
            throw new BuildException(e);
        }
    }

    // TODO this is a pretty expensive operation and so the result
    // should be cached.
    /**
     * Turns all nested resources into corresponding ArchiveFileSets
     * and returns an iterator over the collected archives.
     */
    protected Iterator/*<ArchiveFileset>*/ grabArchives() {
        List l = new LinkedList();
        for (Iterator iter = zips.iterator(); iter.hasNext(); ) {
            l.add(configureArchive(new ZipFileSet(),
                                   (Resource) iter.next()));
        }
        for (Iterator iter = tars.iterator(); iter.hasNext(); ) {
            l.add(configureArchive(new TarFileSet(),
                                   (Resource) iter.next()));
        }
        for (Iterator iter = ars.iterator(); iter.hasNext(); ) {
            l.add(configureArchive(new ArFileSet(),
                                   (Resource) iter.next()));
        }
        for (Iterator iter = cpios.iterator(); iter.hasNext(); ) {
            l.add(configureArchive(new CpioFileSet(),
                                   (Resource) iter.next()));
        }
        return l.iterator();
    }

    /**
     * Configures the archivefileset based on this type's settings,
     * set the source.
     */
    protected ArchiveFileSet configureArchive(ArchiveFileSet afs,
                                              Resource src) {
        afs.setProject(getProject());
        afs.setSrcResource(src);
        return afs;
    }

    /**
     * Overrides the version of DataType to recurse on all DataType
     * child elements that may have been added.
     * @param stk the stack of data types to use (recursively).
     * @param p   the project to use to dereference the references.
     * @throws BuildException on error.
     */
    protected synchronized void dieOnCircularReference(Stack stk, Project p)
        throws BuildException {
        if (isChecked()) {
            return;
        }
        if (isReference()) {
            super.dieOnCircularReference(stk, p);
        } else {
            pushAndInvokeCircularReferenceCheck(zips, stk, p);
            pushAndInvokeCircularReferenceCheck(tars, stk, p);
            pushAndInvokeCircularReferenceCheck(ars, stk, p);
            pushAndInvokeCircularReferenceCheck(cpios, stk, p);
            setChecked(true);
        }
    }

}