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

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.zip.ZipException;

import org.apache.commons.compress.archivers.ArchiveEntry;

/**
 * Extension that adds better handling of extra fields and provides access to
 * the internal and external file attributes.
 */
public class ZipArchiveEntry
    extends java.util.zip.ZipEntry
    implements ArchiveEntry
{
    /**
     * Helper for JDK 1.1
     *
     * @since 1.2
     */
    private static Method c_setCompressedSizeMethod;

    /**
     * Helper for JDK 1.1
     *
     * @since 1.2
     */
    private static final Object c_lockReflection = new Object();

    /**
     * Helper for JDK 1.1
     *
     * @since 1.2
     */
    private static boolean c_triedToGetMethod;

    private final ArrayList m_extraFields = new ArrayList();

    private int m_internalAttributes;
    private long m_externalAttributes;

    /**
     * Helper for JDK 1.1 <-> 1.2 incompatibility.
     *
     * @since 1.2
     */
    private Long m_compressedSize;

    /**
     * Creates a new zip entry with the specified name.
     *
     * @param name the name of entry
     * @since 1.1
     */
    public ZipArchiveEntry( final String name )
    {
        super( name );
    }

    /**
     * Creates a new zip entry with fields taken from the specified zip entry.
     *
     * @param entry the JDK ZipEntry to adapt
     * @exception ZipException if can not create entry
     * @since 1.1
     */
    public ZipArchiveEntry( java.util.zip.ZipEntry entry )
        throws ZipException
    {
        /*
         * REVISIT: call super(entry) instead of this stuff in Ant2,
         * "copy constructor" has not been available in JDK 1.1
         */
        super( entry.getName() );

        setComment( entry.getComment() );
        setMethod( entry.getMethod() );
        setTime( entry.getTime() );

        final long size = entry.getSize();
        if( size > 0 )
        {
            setSize( size );
        }

        final long cSize = entry.getCompressedSize();
        if( cSize > 0 )
        {
            setComprSize( cSize );
        }

        final long crc = entry.getCrc();
        if( crc > 0 )
        {
            setCrc( crc );
        }

        final byte[] extra = entry.getExtra();
        if( extra != null )
        {
            setExtraFields( ExtraFieldUtils.parse( extra ) );
        }
        else
        {
            // initializes extra data to an empty byte array
            setExtra();
        }
    }

    /**
     * Creates a new zip entry with fields taken from the specified zip entry.
     *
     * @param entry the entry to adapt
     * @exception ZipException if can not create entry
     * @since 1.1
     */
    public ZipArchiveEntry( final ZipArchiveEntry entry )
        throws ZipException
    {
        this( (java.util.zip.ZipEntry)entry );
        setInternalAttributes( entry.getInternalAttributes() );
        setExternalAttributes( entry.getExternalAttributes() );
        setExtraFields( entry.getExtraFields() );
    }

    /**
     * Try to get a handle to the setCompressedSize method.
     *
     * @since 1.2
     */
    private static void checkSCS()
    {
        if( !c_triedToGetMethod )
        {
            synchronized( c_lockReflection )
            {
                c_triedToGetMethod = true;
                try
                {
                    c_setCompressedSizeMethod =
                        java.util.zip.ZipEntry.class.getMethod( "setCompressedSize",
                                                                new Class[]{Long.TYPE} );
                }
                catch( NoSuchMethodException nse )
                {
                }
            }
        }
    }

    /**
     * Are we running JDK 1.2 or higher?
     *
     * @return Description of the Returned Value
     * @since 1.2
     */
    private static boolean haveSetCompressedSize()
    {
        checkSCS();
        return c_setCompressedSizeMethod != null;
    }

    /**
     * Invoke setCompressedSize via reflection.
     *
     * @param entry Description of Parameter
     * @param size Description of Parameter
     * @since 1.2
     */
    private static void performSetCompressedSize( final ZipArchiveEntry entry,
                                                  final long size )
    {
        final Long[] s = {new Long( size )};
        try
        {
            c_setCompressedSizeMethod.invoke( entry, s );
        }
        catch( final InvocationTargetException ite )
        {
            final Throwable nested = ite.getTargetException();
            final String message = "Exception setting the compressed size " +
                "of " + entry + ": " + nested.getMessage();
            throw new RuntimeException( message );
        }
        catch( final Throwable t )
        {
            final String message = "Exception setting the compressed size " +
                "of " + entry + ": " + t.getMessage();
            throw new RuntimeException( message );
        }
    }

    /**
     * Make this class work in JDK 1.1 like a 1.2 class. <p>
     *
     * This either stores the size for later usage or invokes setCompressedSize
     * via reflection.</p>
     *
     * @param size The new ComprSize value
     * @since 1.2
     */
    public void setComprSize( final long size )
    {
        if( haveSetCompressedSize() )
        {
            performSetCompressedSize( this, size );
        }
        else
        {
            m_compressedSize = new Long( size );
        }
    }

    /**
     * Sets the external file attributes.
     *
     * @param externalAttributes The new ExternalAttributes value
     * @since 1.1
     */
    public void setExternalAttributes( final long externalAttributes )
    {
        m_externalAttributes = externalAttributes;
    }

    /**
     * Throws an Exception if extra data cannot be parsed into extra fields.
     *
     * @param extra The new Extra value
     * @throws RuntimeException if fail to set extra data
     * @since 1.1
     */
    public void setExtra( final byte[] extra )
        throws RuntimeException
    {
        try
        {
            setExtraFields( ExtraFieldUtils.parse( extra ) );
        }
        catch( final Exception e )
        {
            throw new RuntimeException( e.getMessage() );
        }
    }

    /**
     * Replaces all currently attached extra fields with the new array.
     *
     * @param fields The new ExtraFields value
     * @since 1.1
     */
    public void setExtraFields( final ZipExtraField[] fields )
    {
        m_extraFields.clear();
        for( int i = 0; i < fields.length; i++ )
        {
            m_extraFields.add( fields[ i ] );
        }
        setExtra();
    }

    /**
     * Sets the internal file attributes.
     *
     * @param value The new InternalAttributes value
     * @since 1.1
     */
    public void setInternalAttributes( final int value )
    {
        m_internalAttributes = value;
    }

    /**
     * Retrieves the extra data for the central directory.
     *
     * @return The CentralDirectoryExtra value
     * @since 1.1
     */
    public byte[] getCentralDirectoryExtra()
    {
        return ExtraFieldUtils.mergeCentralDirectoryData( getExtraFields() );
    }

    /**
     * Override to make this class work in JDK 1.1 like a 1.2 class.
     *
     * @return The CompressedSize value
     * @since 1.2
     */
    public long getCompressedSize()
    {
        if( m_compressedSize != null )
        {
            // has been set explicitly and we are running in a 1.1 VM
            return m_compressedSize.longValue();
        }
        return super.getCompressedSize();
    }

    /**
     * Retrieves the external file attributes.
     *
     * @return The ExternalAttributes value
     * @since 1.1
     */
    public long getExternalAttributes()
    {
        return m_externalAttributes;
    }

    /**
     * Retrieves extra fields.
     *
     * @return The ExtraFields value
     * @since 1.1
     */
    public ZipExtraField[] getExtraFields()
    {
        final ZipExtraField[] result = new ZipExtraField[ m_extraFields.size() ];
        return (ZipExtraField[])m_extraFields.toArray( result );
    }

    /**
     * Retrieves the internal file attributes.
     *
     * @return The InternalAttributes value
     * @since 1.1
     */
    public int getInternalAttributes()
    {
        return m_internalAttributes;
    }

    /**
     * Retrieves the extra data for the local file data.
     *
     * @return The LocalFileDataExtra value
     * @since 1.1
     */
    public byte[] getLocalFileDataExtra()
    {
        byte[] extra = getExtra();
        return extra != null ? extra : new byte[ 0 ];
    }

    /**
     * Adds an extra fields - replacing an already present extra field of the
     * same type.
     *
     * @param extraField The feature to be added to the ExtraField attribute
     * @since 1.1
     */
    public void addExtraField( final ZipExtraField extraField )
    {
        final ZipShort type = extraField.getHeaderId();
        boolean done = false;
        for( int i = 0; !done && i < m_extraFields.size(); i++ )
        {
            final ZipExtraField other = (ZipExtraField)m_extraFields.get( i );
            if( other.getHeaderId().equals( type ) )
            {
                m_extraFields.set( i, extraField );
                done = true;
            }
        }
        if( !done )
        {
            m_extraFields.add( extraField );
        }
        setExtra();
    }

    /**
     * Overwrite clone
     *
     * @return Description of the Returned Value
     * @since 1.1
     */
    public Object clone()
    {
        ZipArchiveEntry entry = null;
        try
        {
            entry = new ZipArchiveEntry( (java.util.zip.ZipEntry)super.clone() );
        }
        catch( final Exception e )
        {
            // impossible as extra data is in correct format
            e.printStackTrace();
            return null;
        }

        entry.setInternalAttributes( getInternalAttributes() );
        entry.setExternalAttributes( getExternalAttributes() );
        entry.setExtraFields( getExtraFields() );
        return entry;
    }

    /**
     * Remove an extra fields.
     *
     * @param type Description of Parameter
     * @since 1.1
     */
    public void removeExtraField( final ZipShort type )
    {
        boolean done = false;
        for( int i = 0; !done && i < m_extraFields.size(); i++ )
        {
            if( ( (ZipExtraField)m_extraFields.get( i ) ).getHeaderId().equals( type ) )
            {
                m_extraFields.remove( i );
                done = true;
            }
        }
        if( !done )
        {
            throw new java.util.NoSuchElementException();
        }
        setExtra();
    }

    /**
     * Unfortunately {@link java.util.zip.ZipOutputStream
     * java.util.zip.ZipOutputStream} seems to access the extra data directly,
     * so overriding getExtra doesn't help - we need to modify super's data
     * directly.
     *
     * @since 1.1
     */
    protected void setExtra()
    {
        super.setExtra( ExtraFieldUtils.mergeLocalFileDataData( getExtraFields() ) );
    }
}
