/*
 *  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.IOException;
import java.io.OutputStream;
import org.apache.ant.compress.util.TarStreamFactory;
import org.apache.ant.compress.resources.TarFileSet;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.archivers.tar.TarConstants;
import org.apache.tools.ant.types.ArchiveFileSet;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.Resource;

/**
 * Creates tar archives.
 */
public class Tar extends ArchiveBase {
    private Format format = Format.USTAR;

    public Tar() {
        setFactory(new TarStreamFactory(){
                public ArchiveOutputStream getArchiveStream(OutputStream stream,
                                                            String encoding)
                    throws IOException {
                    TarArchiveOutputStream o =
                        (TarArchiveOutputStream) super.getArchiveStream(stream,
                                                                        encoding);
                    if (format.equals(Format.OLDGNU)) {
                        o.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
                    }
                    else if (format.equals(Format.GNU)) {
                        o.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
                        o.setBigNumberMode(TarArchiveOutputStream
                                           .BIGNUMBER_STAR);
                    }
                    else if (format.equals(Format.STAR)) {
                        o.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
                        o.setBigNumberMode(TarArchiveOutputStream
                                           .BIGNUMBER_STAR);
                    }
                    else if (format.equals(Format.PAX)) {
                        o.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
                        o.setBigNumberMode(TarArchiveOutputStream
                                           .BIGNUMBER_POSIX);
                        o.setAddPaxHeadersForNonAsciiNames(true);
                    }
                    return o;
                }
            });
        setEntryBuilder(
              new ArchiveBase.EntryBuilder() {
                public ArchiveEntry buildEntry(ArchiveBase.ResourceWithFlags r) {
                    boolean isDir = r.getResource().isDirectory();
                    String name = r.getName();
                    if (isDir && !name.endsWith("/")) {
                        name += "/";
                    } else if (!isDir && name.endsWith("/")) {
                        name = name.substring(0, name.length() - 1);
                    }
                    TarArchiveEntry ent =
                        new TarArchiveEntry(name, getPreserveLeadingSlashes());
                    ent.setModTime(round(r.getResource().getLastModified(),
                                         1000));
                    ent.setSize(isDir ? 0 : r.getResource().getSize());

                    if (!isDir && r.getCollectionFlags().hasModeBeenSet()) {
                        ent.setMode(r.getCollectionFlags().getMode());
                    } else if (isDir
                               && r.getCollectionFlags().hasDirModeBeenSet()) {
                        ent.setMode(r.getCollectionFlags().getDirMode());
                    } else if (r.getResourceFlags().hasModeBeenSet()) {
                        ent.setMode(r.getResourceFlags().getMode());
                    } else {
                        ent.setMode(isDir
                                    ? ArchiveFileSet.DEFAULT_DIR_MODE
                                    : ArchiveFileSet.DEFAULT_FILE_MODE);
                    }

                    if (r.getResourceFlags().hasUserIdBeenSet()) {
                        ent.setUserId(r.getResourceFlags().getUserId());
                    } else if (r.getCollectionFlags().hasUserIdBeenSet()) {
                        ent.setUserId(r.getCollectionFlags().getUserId());
                    }

                    if (r.getResourceFlags().hasGroupIdBeenSet()) {
                        ent.setGroupId(r.getResourceFlags().getGroupId());
                    } else if (r.getCollectionFlags().hasGroupIdBeenSet()) {
                        ent.setGroupId(r.getCollectionFlags().getGroupId());
                    }
 
                    if (r.getResourceFlags().hasUserNameBeenSet()) {
                        ent.setUserName(r.getResourceFlags().getUserName());
                    } else if (r.getCollectionFlags().hasUserNameBeenSet()) {
                        ent.setUserName(r.getCollectionFlags().getUserName());
                    }

                    if (r.getResourceFlags().hasGroupNameBeenSet()) {
                        ent.setGroupName(r.getResourceFlags().getGroupName());
                    } else if (r.getCollectionFlags().hasGroupNameBeenSet()) {
                        ent.setGroupName(r.getCollectionFlags().getGroupName());
                    }
 
                    return ent;
                }
            });
        setFileSetBuilder(new ArchiveBase.FileSetBuilder() {
                public ArchiveFileSet buildFileSet(Resource dest) {
                    ArchiveFileSet afs = new TarFileSet();
                    afs.setSrcResource(dest);
                    return afs;
                }
            });
    }

    /**
     * The format to use.
     */
    public void setFormat(Format f) {
        format = f;
    }

    /**
     * The supported tar formats for entries with long file names.
     */
    public final static class Format extends EnumeratedAttribute {
        private static final String USTAR_NAME = "ustar";
        private static final String OLDGNU_NAME = "oldgnu";
        private static final String GNU_NAME = "gnu";
        private static final String STAR_NAME = "star";
        private static final String PAX_NAME = "pax";

        public static final Format USTAR = new Format(USTAR_NAME);
        public static final Format OLDGNU = new Format(OLDGNU_NAME);
        public static final Format GNU = new Format(GNU_NAME);
        public static final Format STAR = new Format(STAR_NAME);
        public static final Format PAX = new Format(PAX_NAME);

        public Format(String v) {
            setValue(v);
        }

        public Format() {
            setValue(USTAR_NAME);
        }

        public String[] getValues() {
            return new String[] {
                USTAR_NAME, OLDGNU_NAME, GNU_NAME,
                STAR_NAME, PAX_NAME
            };
        }

        public boolean equals(Object other) {
            return other instanceof Format
                && ((Format) other).getValue().equals(getValue());
        }
    }
}