/*
 * 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.commons.compress.archivers.dump;

import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.compress.archivers.ArchiveEntry;

/**
 * This class represents an entry in a Dump archive. It consists
 * of the entry's header, the entry's File and any extended attributes.
 * <p>
 * DumpEntries that are created from the header bytes read from
 * an archive are instantiated with the DumpArchiveEntry( byte[] )
 * constructor. These entries will be used when extracting from
 * or listing the contents of an archive. These entries have their
 * header filled in using the header bytes. They also set the File
 * to null, since they reference an archive entry not a file.
 * <p>
 * DumpEntries can also be constructed from nothing but a name.
 * This allows the programmer to construct the entry by hand, for
 * instance when only an InputStream is available for writing to
 * the archive, and the header information is constructed from
 * other information. In this case the header fields are set to
 * defaults and the File is set to null.
 *
 * <p>
 * The C structure for a Dump Entry's header is:
 * <pre>
 * #define TP_BSIZE    1024          // size of each file block
 * #define NTREC       10            // number of blocks to write at once
 * #define HIGHDENSITYTREC 32        // number of blocks to write on high-density tapes
 * #define TP_NINDIR   (TP_BSIZE/2)  // number if indirect inodes in record
 * #define TP_NINOS    (TP_NINDIR / sizeof (int32_t))
 * #define LBLSIZE     16
 * #define NAMELEN     64
 *
 * #define OFS_MAGIC     (int)60011  // old format magic value
 * #define NFS_MAGIC     (int)60012  // new format magic value
 * #define FS_UFS2_MAGIC (int)0x19540119
 * #define CHECKSUM      (int)84446  // constant used in checksum algorithm
 *
 * struct  s_spcl {
 *   int32_t c_type;             // record type (see below)
 *   int32_t <b>c_date</b>;             // date of this dump
 *   int32_t <b>c_ddate</b>;            // date of previous dump
 *   int32_t c_volume;           // dump volume number
 *   u_int32_t c_tapea;          // logical block of this record
 *   dump_ino_t c_ino;           // number of inode
 *   int32_t <b>c_magic</b>;            // magic number (see above)
 *   int32_t c_checksum;         // record checksum
 * #ifdef  __linux__
 *   struct  new_bsd_inode c_dinode;
 * #else
 * #ifdef sunos
 *   struct  new_bsd_inode c_dinode;
 * #else
 *   struct  dinode  c_dinode;   // ownership and mode of inode
 * #endif
 * #endif
 *   int32_t c_count;            // number of valid c_addr entries
 *   union u_data c_data;        // see above
 *   char    <b>c_label[LBLSIZE]</b>;   // dump label
 *   int32_t <b>c_level</b>;            // level of this dump
 *   char    <b>c_filesys[NAMELEN]</b>; // name of dumpped file system
 *   char    <b>c_dev[NAMELEN]</b>;     // name of dumpped device
 *   char    <b>c_host[NAMELEN]</b>;    // name of dumpped host
 *   int32_t c_flags;            // additional information (see below)
 *   int32_t c_firstrec;         // first record on volume
 *   int32_t c_ntrec;            // blocksize on volume
 *   int32_t c_extattributes;    // additional inode info (see below)
 *   int32_t c_spare[30];        // reserved for future uses
 * } s_spcl;
 *
 * //
 * // flag values
 * //
 * #define DR_NEWHEADER     0x0001  // new format tape header
 * #define DR_NEWINODEFMT   0x0002  // new format inodes on tape
 * #define DR_COMPRESSED    0x0080  // dump tape is compressed
 * #define DR_METAONLY      0x0100  // only the metadata of the inode has been dumped
 * #define DR_INODEINFO     0x0002  // [SIC] TS_END header contains c_inos information
 * #define DR_EXTATTRIBUTES 0x8000
 *
 * //
 * // extattributes inode info
 * //
 * #define EXT_REGULAR         0
 * #define EXT_MACOSFNDRINFO   1
 * #define EXT_MACOSRESFORK    2
 * #define EXT_XATTR           3
 *
 * // used for EA on tape
 * #define EXT2_GOOD_OLD_INODE_SIZE    128
 * #define EXT2_XATTR_MAGIC        0xEA020000  // block EA
 * #define EXT2_XATTR_MAGIC2       0xEA020001  // in inode EA
 * </pre>
 * The fields in <b>bold</b> are the same for all blocks. (This permitted
 * multiple dumps to be written to a single tape.)
 * </p>
 *
 * <p>
 * The C structure for the inode (file) information is:
 * <pre>
 * struct bsdtimeval {           //  **** alpha-*-linux is deviant
 *   __u32   tv_sec;
 *   __u32   tv_usec;
 * };
 *
 * #define NDADDR      12
 * #define NIADDR       3
 *
 * //
 * // This is the new (4.4) BSD inode structure
 * // copied from the FreeBSD 2.0 <ufs/ufs/dinode.h> include file
 * //
 * struct new_bsd_inode {
 *   __u16       di_mode;           // file type, standard Unix permissions
 *   __s16       di_nlink;          // number of hard links to file.
 *   union {
 *      __u16       oldids[2];
 *      __u32       inumber;
 *   }           di_u;
 *   u_quad_t    di_size;           // file size
 *   struct bsdtimeval   di_atime;  // time file was last accessed
 *   struct bsdtimeval   di_mtime;  // time file was last modified
 *   struct bsdtimeval   di_ctime;  // time file was created
 *   __u32       di_db[NDADDR];
 *   __u32       di_ib[NIADDR];
 *   __u32       di_flags;          //
 *   __s32       di_blocks;         // number of disk blocks
 *   __s32       di_gen;            // generation number
 *   __u32       di_uid;            // user id (see /etc/passwd)
 *   __u32       di_gid;            // group id (see /etc/group)
 *   __s32       di_spare[2];       // unused
 * };
 * </pre>
 * It is important to note that the header DOES NOT have the name of the
 * file. It can't since hard links mean that you may have multiple filenames
 * for a single physical file. You must read the contents of the directory
 * entries to learn the mapping(s) from filename to inode.
 * </p>
 *
 * <p>
 * The C structure that indicates if a specific block is a real block
 * that contains data or is a sparse block that is not persisted to the
 * disk is:
 * <pre>
 * #define TP_BSIZE    1024
 * #define TP_NINDIR   (TP_BSIZE/2)
 *
 * union u_data {
 *   char    s_addrs[TP_NINDIR]; // 1 => data; 0 => hole in inode
 *   int32_t s_inos[TP_NINOS];   // table of first inode on each volume
 * } u_data;
 * </pre></p>
 *
 * @NotThreadSafe
 */
public class DumpArchiveEntry implements ArchiveEntry {
    private String name;
    private TYPE type = TYPE.UNKNOWN;
    private int mode;
    private Set<PERMISSION> permissions = Collections.emptySet();
    private long size;
    private long atime;
    private long mtime;
    private int uid;
    private int gid;

    /**
     * Currently unused
     */
    private final DumpArchiveSummary summary = null;

    // this information is available from standard index.
    private final TapeSegmentHeader header = new TapeSegmentHeader();
    private String simpleName;
    private String originalName;

    // this information is available from QFA index
    private int volume;
    private long offset;
    private int ino;
    private int nlink;
    private long ctime;
    private int generation;
    private boolean isDeleted;

    /**
     * Default constructor.
     */
    public DumpArchiveEntry() {
    }

    /**
     * Constructor taking only filename.
     * @param name pathname
     * @param simpleName actual filename.
     */
    public DumpArchiveEntry(String name, String simpleName) {
        setName(name);
        this.simpleName = simpleName;
    }

    /**
     * Constructor taking name, inode and type.
     *
     * @param name
     * @param simpleName
     * @param ino
     * @param type
     */
    protected DumpArchiveEntry(String name, String simpleName, int ino,
                               TYPE type) {
        setType(type);
        setName(name);
        this.simpleName = simpleName;
        this.ino = ino;
        this.offset = 0;
    }

    /**
     * Constructor taking tape buffer.
     * @param buffer
     * @param offset
     */

    /**
     * Returns the path of the entry.
     * @return the path of the entry.
     */
    public String getSimpleName() {
        return simpleName;
    }

    /**
     * Sets the path of the entry.
     */
    protected void setSimpleName(String simpleName) {
        this.simpleName = simpleName;
    }

    /**
     * Returns the ino of the entry.
     */
    public int getIno() {
        return header.getIno();
    }

    /**
     * Return the number of hard links to the entry.
     */
    public int getNlink() {
        return nlink;
    }

    /**
     * Set the number of hard links.
     */
    public void setNlink(int nlink) {
        this.nlink = nlink;
    }

    /**
     * Get file creation time.
     */
    public Date getCreationTime() {
        return new Date(ctime);
    }

    /**
     * Set the file creation time.
     */
    public void setCreationTime(Date ctime) {
        this.ctime = ctime.getTime();
    }

    /**
     * Return the generation of the file.
     */
    public int getGeneration() {
        return generation;
    }

    /**
     * Set the generation of the file.
     */
    public void setGeneration(int generation) {
        this.generation = generation;
    }

    /**
     * Has this file been deleted? (On valid on incremental dumps.)
     */
    public boolean isDeleted() {
        return isDeleted;
    }

    /**
     * Set whether this file has been deleted.
     */
    public void setDeleted(boolean isDeleted) {
        this.isDeleted = isDeleted;
    }

    /**
     * Return the offset within the archive
     */
    public long getOffset() {
        return offset;
    }

    /**
     * Set the offset within the archive.
     */
    public void setOffset(long offset) {
        this.offset = offset;
    }

    /**
     * Return the tape volume where this file is located.
     */
    public int getVolume() {
        return volume;
    }

    /**
     * Set the tape volume.
     */
    public void setVolume(int volume) {
        this.volume = volume;
    }

    /**
     * Return the type of the tape segment header.
     */
    public DumpArchiveConstants.SEGMENT_TYPE getHeaderType() {
        return header.getType();
    }

    /**
     * Return the number of records in this segment.
     */
    public int getHeaderCount() {
        return header.getCount();
    }

    /**
     * Return the number of sparse records in this segment.
     */
    public int getHeaderHoles() {
        return header.getHoles();
    }

    /**
     * Is this a sparse record?
     */
    public boolean isSparseRecord(int idx) {
        return (header.getCdata(idx) & 0x01) == 0;
    }

    /**
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        return ino;
    }

    /**
     * @see java.lang.Object#equals(Object o)
     */
    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (o == null || !o.getClass().equals(getClass())) {
            return false;
        }

        DumpArchiveEntry rhs = (DumpArchiveEntry) o;

        if ((header == null) || (rhs.header == null)) {
            return false;
        }

        if (ino != rhs.ino) {
            return false;
        }

        if ((summary == null && rhs.summary != null)
            || (summary != null && !summary.equals(rhs.summary))) {
            return false;
        }

        return true;
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return getName();
    }

    /**
     * Populate the dump archive entry and tape segment header with
     * the contents of the buffer.
     *
     * @param buffer
     * @throws Exception
     */
    static DumpArchiveEntry parse(byte[] buffer) {
        DumpArchiveEntry entry = new DumpArchiveEntry();
        TapeSegmentHeader header = entry.header;

        header.type = DumpArchiveConstants.SEGMENT_TYPE.find(DumpArchiveUtil.convert32(
                    buffer, 0));

        //header.dumpDate = new Date(1000L * DumpArchiveUtil.convert32(buffer, 4));
        //header.previousDumpDate = new Date(1000L * DumpArchiveUtil.convert32(
        //            buffer, 8));
        header.volume = DumpArchiveUtil.convert32(buffer, 12);
        //header.tapea = DumpArchiveUtil.convert32(buffer, 16);
        entry.ino = header.ino = DumpArchiveUtil.convert32(buffer, 20);

        //header.magic = DumpArchiveUtil.convert32(buffer, 24);
        //header.checksum = DumpArchiveUtil.convert32(buffer, 28);
        int m = DumpArchiveUtil.convert16(buffer, 32);

        // determine the type of the file.
        entry.setType(TYPE.find((m >> 12) & 0x0F));

        // determine the standard permissions
        entry.setMode(m);

        entry.nlink = DumpArchiveUtil.convert16(buffer, 34);
        // inumber, oldids?
        entry.setSize(DumpArchiveUtil.convert64(buffer, 40));

        long t = (1000L * DumpArchiveUtil.convert32(buffer, 48)) +
            (DumpArchiveUtil.convert32(buffer, 52) / 1000);
        entry.setAccessTime(new Date(t));
        t = (1000L * DumpArchiveUtil.convert32(buffer, 56)) +
            (DumpArchiveUtil.convert32(buffer, 60) / 1000);
        entry.setLastModifiedDate(new Date(t));
        t = (1000L * DumpArchiveUtil.convert32(buffer, 64)) +
            (DumpArchiveUtil.convert32(buffer, 68) / 1000);
        entry.ctime = t;

        // db: 72-119 - direct blocks
        // id: 120-131 - indirect blocks
        //entry.flags = DumpArchiveUtil.convert32(buffer, 132);
        //entry.blocks = DumpArchiveUtil.convert32(buffer, 136);
        entry.generation = DumpArchiveUtil.convert32(buffer, 140);
        entry.setUserId(DumpArchiveUtil.convert32(buffer, 144));
        entry.setGroupId(DumpArchiveUtil.convert32(buffer, 148));
        // two 32-bit spare values.
        header.count = DumpArchiveUtil.convert32(buffer, 160);

        header.holes = 0;

        for (int i = 0; (i < 512) && (i < header.count); i++) {
            if (buffer[164 + i] == 0) {
                header.holes++;
            }
        }

        System.arraycopy(buffer, 164, header.cdata, 0, 512);

        entry.volume = header.getVolume();

        //entry.isSummaryOnly = false;
        return entry;
    }

    /**
     * Update entry with information from next tape segment header.
     */
    void update(byte[] buffer) {
        header.volume = DumpArchiveUtil.convert32(buffer, 16);
        header.count = DumpArchiveUtil.convert32(buffer, 160);

        header.holes = 0;

        for (int i = 0; (i < 512) && (i < header.count); i++) {
            if (buffer[164 + i] == 0) {
                header.holes++;
            }
        }

        System.arraycopy(buffer, 164, header.cdata, 0, 512);
    }

    /**
     * Archive entry as stored on tape. There is one TSH for (at most)
     * every 512k in the file.
     */
    static class TapeSegmentHeader {
        private DumpArchiveConstants.SEGMENT_TYPE type;
        private int volume;
        private int ino;
        private int count;
        private int holes;
        private final byte[] cdata = new byte[512]; // map of any 'holes'

        public DumpArchiveConstants.SEGMENT_TYPE getType() {
            return type;
        }

        public int getVolume() {
            return volume;
        }

        public int getIno() {
            return ino;
        }

        void setIno(int ino) {
            this.ino = ino;
        }

        public int getCount() {
            return count;
        }

        public int getHoles() {
            return holes;
        }

        public int getCdata(int idx) {
            return cdata[idx];
        }
    }

    /**
     * Returns the name of the entry.
     * @return the name of the entry.
     */
    public String getName() {
        return name;
    }

    /**
     * Returns the unmodified name of the entry.
     * @return the name of the entry.
     */
    String getOriginalName() {
        return originalName;
    }

    /**
     * Sets the name of the entry.
     */
    public final void setName(String name) {
        this.originalName = name;
        if (name != null) {
            if (isDirectory() && !name.endsWith("/")) {
                name += "/";
            }
            if (name.startsWith("./")) {
                name = name.substring(2);
            }
        }
        this.name = name;
    }

    public Date getLastModifiedDate() {
        return new Date(mtime);
    }

    /**
     * Is this a directory?
     */
    public boolean isDirectory() {
        return type == TYPE.DIRECTORY;
    }

    /**
     * Is this a regular file?
     */
    public boolean isFile() {
        return type == TYPE.FILE;
    }

    /**
     * Is this a network device?
     */
    public boolean isSocket() {
        return type == TYPE.SOCKET;
    }

    /**
     * Is this a character device?
     */
    public boolean isChrDev() {
        return type == TYPE.CHRDEV;
    }

    /**
     * Is this a block device?
     */
    public boolean isBlkDev() {
        return type == TYPE.BLKDEV;
    }

    /**
     * Is this a fifo/pipe?
     */
    public boolean isFifo() {
        return type == TYPE.FIFO;
    }

    /**
     * Get the type of the entry.
     */
    public TYPE getType() {
        return type;
    }

    /**
     * Set the type of the entry.
     */
    public void setType(TYPE type) {
        this.type = type;
    }

    /**
     * Return the access permissions on the entry.
     */
    public int getMode() {
        return mode;
    }

    /**
     * Set the access permissions on the entry.
     */
    public void setMode(int mode) {
        this.mode = mode & 07777;
        this.permissions = PERMISSION.find(mode);
    }

    /**
     * Returns the permissions on the entry.
     */
    public Set<PERMISSION> getPermissions() {
        return permissions;
    }

    /**
     * Returns the size of the entry.
     */
    public long getSize() {
        return isDirectory() ? SIZE_UNKNOWN : size;
    }

    /**
     * Returns the size of the entry as read from the archive.
     */
    long getEntrySize() {
        return size;
    }

    /**
     * Set the size of the entry.
     */
    public void setSize(long size) {
        this.size = size;
    }

    /**
     * Set the time the file was last modified.
     */
    public void setLastModifiedDate(Date mtime) {
        this.mtime = mtime.getTime();
    }

    /**
     * Returns the time the file was last accessed.
     */
    public Date getAccessTime() {
        return new Date(atime);
    }

    /**
     * Set the time the file was last accessed.
     */
    public void setAccessTime(Date atime) {
        this.atime = atime.getTime();
    }

    /**
     * Return the user id.
     */
    public int getUserId() {
        return uid;
    }

    /**
     * Set the user id.
     */
    public void setUserId(int uid) {
        this.uid = uid;
    }

    /**
     * Return the group id
     */
    public int getGroupId() {
        return gid;
    }

    /**
     * Set the group id.
     */
    public void setGroupId(int gid) {
        this.gid = gid;
    }

    public enum TYPE {
        WHITEOUT(14),
        SOCKET(12),
        LINK(10),
        FILE(8),
        BLKDEV(6),
        DIRECTORY(4),
        CHRDEV(2),
        FIFO(1),
        UNKNOWN(15);

        private int code;

        private TYPE(int code) {
            this.code = code;
        }

        public static TYPE find(int code) {
            TYPE type = UNKNOWN;

            for (TYPE t : TYPE.values()) {
                if (code == t.code) {
                    type = t;
                }
            }

            return type;
        }
    }

    public enum PERMISSION {
        SETUID(04000),
        SETGUI(02000),
        STICKY(01000),
        USER_READ(00400),
        USER_WRITE(00200),
        USER_EXEC(00100),
        GROUP_READ(00040),
        GROUP_WRITE(00020),
        GROUP_EXEC(00010),
        WORLD_READ(00004),
        WORLD_WRITE(00002),
        WORLD_EXEC(00001);

        private int code;

        private PERMISSION(int code) {
            this.code = code;
        }

        public static Set<PERMISSION> find(int code) {
            Set<PERMISSION> set = new HashSet<PERMISSION>();

            for (PERMISSION p : PERMISSION.values()) {
                if ((code & p.code) == p.code) {
                    set.add(p);
                }
            }

            if (set.isEmpty()) {
                return Collections.emptySet();
            }

            return EnumSet.copyOf(set);
        }
    }
}
