/* ====================================================================
   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.poi.hpsf;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

import javax.xml.bind.DatatypeConverter;

import org.apache.poi.hpsf.wellknown.PropertyIDMap;
import org.apache.poi.util.CodePageUtil;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianByteArrayInputStream;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;

/**
 * A property in a {@link Section} of a {@link PropertySet}.<p>
 *
 * The property's {@code ID} gives the property a meaning
 * in the context of its {@link Section}. Each {@link Section} spans
 * its own name space of property IDs.<p>
 *
 * The property's {@code type} determines how its
 * {@code value} is interpreted. For example, if the type is
 * {@link Variant#VT_LPSTR} (byte string), the value consists of a
 * DWord telling how many bytes the string contains. The bytes follow
 * immediately, including any null bytes that terminate the
 * string. The type {@link Variant#VT_I4} denotes a four-byte integer
 * value, {@link Variant#VT_FILETIME} some date and time (of a file).<p>
 *
 * Please note that not all {@link Variant} types yet. This might change
 * over time but largely depends on your feedback so that the POI team knows
 * which variant types are really needed. So please feel free to submit error
 * reports or patches for the types you need.
 *
 * @see Section
 * @see Variant
 * @see <a href="https://msdn.microsoft.com/en-us/library/dd942421.aspx">
 * [MS-OLEPS]: Object Linking and Embedding (OLE) Property Set Data Structures</a>
 */
public class Property {

    /**
     * Default codepage for {@link CodePageString CodePageStrings}
     */
    public static final int DEFAULT_CODEPAGE = CodePageUtil.CP_WINDOWS_1252; 
    
    private static final POILogger LOG = POILogFactory.getLogger(Property.class);
    
    /** The property's ID. */
    private long id;

    /** The property's type. */
    private long type;

    /** The property's value. */
    private Object value;


    /**
     * Creates an empty property. It must be filled using the set method to be usable.
     */
    public Property() {
    }

    /**
     * Creates a {@code Property} as a copy of an existing {@code Property}.
     *
     * @param p The property to copy.
     */
    public Property(Property p) {
        this(p.id, p.type, p.value);
    }

    /**
     * Creates a property.
     *
     * @param id the property's ID.
     * @param type the property's type, see {@link Variant}.
     * @param value the property's value. Only certain types are allowed, see
     *        {@link Variant}.
     */
    public Property(final long id, final long type, final Object value) {
        this.id = id;
        this.type = type;
        this.value = value;
    }

    /**
     * Creates a {@link Property} instance by reading its bytes
     * from the property set stream.
     *
     * @param id The property's ID.
     * @param src The bytes the property set stream consists of.
     * @param offset The property's type/value pair's offset in the
     * section.
     * @param length The property's type/value pair's length in bytes.
     * @param codepage The section's and thus the property's
     * codepage. It is needed only when reading string values.
     * @exception UnsupportedEncodingException if the specified codepage is not
     * supported.
     */
    public Property(final long id, final byte[] src, final long offset, final int length, final int codepage)
    throws UnsupportedEncodingException {
        this.id = id;

        /*
         * ID 0 is a special case since it specifies a dictionary of
         * property IDs and property names.
         */
        if (id == 0) {
            throw new UnsupportedEncodingException("Dictionary not allowed here");
        }

        int o = (int) offset;
        type = LittleEndian.getUInt(src, o);
        o += LittleEndianConsts.INT_SIZE;

        try {
            value = VariantSupport.read(src, o, length, (int) type, codepage);
        } catch (UnsupportedVariantTypeException ex) {
            VariantSupport.writeUnsupportedTypeMessage(ex);
            value = ex.getValue();
        }
    }

    /**
     * Creates a {@link Property} instance by reading its bytes
     * from the property set stream.
     *
     * @param id The property's ID.
     * @param leis The bytes the property set stream consists of.
     * @param length The property's type/value pair's length in bytes.
     * @param codepage The section's and thus the property's
     * codepage. It is needed only when reading string values.
     * @exception UnsupportedEncodingException if the specified codepage is not
     * supported.
     */
    public Property(final long id, LittleEndianByteArrayInputStream leis, final int length, final int codepage)
    throws UnsupportedEncodingException {
        this.id = id;

        /*
         * ID 0 is a special case since it specifies a dictionary of
         * property IDs and property names.
         */
        if (id == 0) {
            throw new UnsupportedEncodingException("Dictionary not allowed here");
        }

        type = leis.readUInt();

        try {
            value = VariantSupport.read(leis, length, (int) type, codepage);
        } catch (UnsupportedVariantTypeException ex) {
            VariantSupport.writeUnsupportedTypeMessage(ex);
            value = ex.getValue();
        }
    }


    /**
     * Returns the property's ID.
     *
     * @return The ID value
     */
    public long getID() {
        return id;
    }

    /**
     * Sets the property's ID.
     *
     * @param id the ID
     */
    public void setID(final long id) {
        this.id = id;
    }

    /**
     * Returns the property's type.
     *
     * @return The type value
     */
    public long getType() {
        return type;
    }

    /**
     * Sets the property's type.
     *
     * @param type the property's type
     */
    public void setType(final long type) {
        this.type = type;
    }

    /**
     * Returns the property's value.
     *
     * @return The property's value
     */
    public Object getValue() {
        return value;
    }

    /**
     * Sets the property's value.
     *
     * @param value the property's value
     */
    public void setValue(final Object value) {
        this.value = value;
    }








    /**
     * Returns the property's size in bytes. This is always a multiple of 4.
     *
     * @return the property's size in bytes
     *
     * @exception WritingNotSupportedException if HPSF does not yet support the
     * property's variant type.
     */
    protected int getSize(int codepage) throws WritingNotSupportedException
    {
        int length = Variant.getVariantLength(type);
        if (length >= 0  || type == Variant.VT_EMPTY) {
            /* Fixed length */
            return length;
        }
        if (length == -2) {
            /* Unknown length */
            throw new WritingNotSupportedException(type, null);
        }

        /* Variable length: */
        if (type == Variant.VT_LPSTR || type == Variant.VT_LPWSTR) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                length = write(bos, codepage) - 2*LittleEndianConsts.INT_SIZE;
                /* Pad to multiples of 4. */
                length += (4 - (length & 0x3)) & 0x3;
                return length;
            } catch (IOException e) {
                throw new WritingNotSupportedException(type, value);
            }
        }

        throw new WritingNotSupportedException(type, value);
    }



    /**
     * Compares two properties.<p>
     *
     * Please beware that a property with
     * ID == 0 is a special case: It does not have a type, and its value is the
     * section's dictionary. Another special case are strings: Two properties
     * may have the different types Variant.VT_LPSTR and Variant.VT_LPWSTR;
     *
     * @see Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object o) {
        if (!(o instanceof Property)) {
            return false;
        }
        final Property p = (Property) o;
        final Object pValue = p.getValue();
        final long pId = p.getID();
        if (id != pId || (id != 0 && !typesAreEqual(type, p.getType()))) {
            return false;
        }
        if (value == null && pValue == null) {
            return true;
        }
        if (value == null || pValue == null) {
            return false;
        }

        /* It's clear now that both values are non-null. */
        final Class<?> valueClass = value.getClass();
        final Class<?> pValueClass = pValue.getClass();
        if (!(valueClass.isAssignableFrom(pValueClass)) &&
            !(pValueClass.isAssignableFrom(valueClass))) {
            return false;
        }

        if (value instanceof byte[]) {
            // compare without padding bytes
            byte[] thisVal = (byte[]) value, otherVal = (byte[]) pValue;
            int len = unpaddedLength(thisVal);
            if (len != unpaddedLength(otherVal)) {
                return false;
            }
            for (int i=0; i<len; i++) {
                if (thisVal[i] != otherVal[i]) {
                    return false;
                }
            }
            return true;
        }

        return value.equals(pValue);
    }

    /**
     * Byte arrays can be 0-padded up to 3 bytes to form a full quad array.
     * This returns the truncated length without the potentially 0-padded bytes
     *
     * @param buf the bytes
     * @return the truncated size with a maximum of 4 bytes shorter (3 bytes + trailing 0 of strings)
     */
    private static int unpaddedLength(byte[] buf) {
        int len;
        for (len = buf.length; len > 0 && len > buf.length-4 && buf[len-1] == 0; len--);
        return len;
    }


    private boolean typesAreEqual(final long t1, final long t2) {
        return (t1 == t2 ||
            (t1 == Variant.VT_LPSTR && t2 == Variant.VT_LPWSTR) ||
            (t2 == Variant.VT_LPSTR && t1 == Variant.VT_LPWSTR));
    }



    /**
     * @see Object#hashCode()
     */
    @Override
    public int hashCode() {
        long hashCode = 0;
        hashCode += id;
        hashCode += type;
        if (value != null) {
            hashCode += value.hashCode();
        }
        return (int) (hashCode & 0x0ffffffffL );

    }



    /**
     * @see Object#toString()
     */
    @Override
    public String toString() {
        return toString(Property.DEFAULT_CODEPAGE, null);
    }
    
    public String toString(int codepage, PropertyIDMap idMap) {
        final StringBuilder b = new StringBuilder();
        b.append("Property[");
        b.append("id: ");
        b.append(id);
        String idName = (idMap == null) ? null : idMap.get(id);
        if (idName == null) {
            idName = PropertyIDMap.getFallbackProperties().get(id);
        }
        if (idName != null) {
            b.append(" (");
            b.append(idName);
            b.append(")");
        }
        b.append(", type: ");
        b.append(getType());
        b.append(" (");
        b.append(getVariantName());
        b.append(") ");
        final Object value = getValue();
        b.append(", value: ");
        if (value instanceof String) {
            b.append((String)value);
            b.append("\n");
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                write(bos, codepage);
            } catch (Exception e) {
                LOG.log(POILogger.WARN, "can't serialize string", e);
            }
            
            // skip length field
            if(bos.size() > 2*LittleEndianConsts.INT_SIZE) {
                final String hex = HexDump.dump(bos.toByteArray(), -2*LittleEndianConsts.INT_SIZE, 2*LittleEndianConsts.INT_SIZE);
                b.append(hex);
            }
        } else if (value instanceof byte[]) {
            b.append("\n");
            byte[] bytes = (byte[])value;
            if(bytes.length > 0) {
                String hex = HexDump.dump(bytes, 0L, 0);
                b.append(hex);
            }
        } else if (value instanceof java.util.Date) {
            java.util.Date d = (java.util.Date)value;
            long filetime = Filetime.dateToFileTime(d);
            if (Filetime.isUndefined(d)) {
                b.append("<undefined>");
            } else if ((filetime >>> 32) == 0) {
                // if the upper dword isn't set, we deal with time intervals
                long l = filetime*100;
                TimeUnit tu = TimeUnit.NANOSECONDS;
                final long hr  = tu.toHours(l);
                l -= TimeUnit.HOURS.toNanos(hr);
                final long min = tu.toMinutes(l);
                l -= TimeUnit.MINUTES.toNanos(min);
                final long sec = tu.toSeconds(l);
                l -= TimeUnit.SECONDS.toNanos(sec);
                final long ms  = tu.toMillis(l);
                
                String str = String.format(Locale.ROOT, "%02d:%02d:%02d.%03d",hr,min,sec,ms);
                b.append(str);
            } else {
                Calendar cal = Calendar.getInstance(LocaleUtil.TIMEZONE_UTC, Locale.ROOT);
                cal.setTime(d);
                // use ISO-8601 timestamp format
                b.append(DatatypeConverter.printDateTime(cal));
            }
        } else if (type == Variant.VT_EMPTY || type == Variant.VT_NULL || value == null) {
            b.append("null");
        } else {
            b.append(value.toString());
            
            String decoded = decodeValueFromID();
            if (decoded != null) {
                b.append(" (");
                b.append(decoded);
                b.append(")");
            }
        }
        b.append(']');
        return b.toString();
    }

    private String getVariantName() {
        if (getID() == 0) {
            return "dictionary";
        }
        return Variant.getVariantName(getType());
    }
    
    private String decodeValueFromID() {
        try {
            switch((int)getID()) {
                case PropertyIDMap.PID_CODEPAGE:
                    return CodePageUtil.codepageToEncoding(((Number)value).intValue());
                case PropertyIDMap.PID_LOCALE:
                    return LocaleUtil.getLocaleFromLCID(((Number)value).intValue());
            }
        } catch (Exception e) {
            LOG.log(POILogger.WARN, "Can't decode id "+getID());
        }
        return null;
    }
    
    /**
     * Writes the property to an output stream.
     *
     * @param out The output stream to write to.
     * @param codepage The codepage to use for writing non-wide strings
     * @return the number of bytes written to the stream
     *
     * @exception IOException if an I/O error occurs
     * @exception WritingNotSupportedException if a variant type is to be
     * written that is not yet supported
     */
    public int write(final OutputStream out, final int codepage)
    throws IOException, WritingNotSupportedException {
        int length = 0;
        long variantType = getType();

        /* Ensure that wide strings are written if the codepage is Unicode. */
//        if (codepage == CodePageUtil.CP_UNICODE && variantType == Variant.VT_LPSTR) {
//            variantType = Variant.VT_LPWSTR;
//        }

        if (variantType == Variant.VT_LPSTR && codepage != CodePageUtil.CP_UTF16) {
            String csStr = CodePageUtil.codepageToEncoding(codepage > 0 ? codepage : Property.DEFAULT_CODEPAGE);
            if (!Charset.forName(csStr).newEncoder().canEncode((String)value)) {
                variantType = Variant.VT_LPWSTR;
            }
        }

        LittleEndian.putUInt(variantType, out);
        length += LittleEndianConsts.INT_SIZE;
        length += VariantSupport.write(out, variantType, getValue(), codepage);
        return length;
    }

}
