/* ====================================================================
   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.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

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.
     *
     * @param property The integer property to check
     *
     * @return the property's size in bytes
     *
     * @exception WritingNotSupportedException if HPSF does not yet support the
     * property's variant type.
     */
    protected int getSize(int property) 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, property) - 2*LittleEndianConsts.INT_SIZE;
                /* Pad to multiples of 4. */
                length += (4 - (length & 0x3)) & 0x3;
                return length;
            } catch (IOException e) {
                throw new WritingNotSupportedException(type, this.value);
            }
        }

        throw new WritingNotSupportedException(type, this.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) {
        final int end = (buf.length-(buf.length+3)%4);
        for (int i = buf.length; i>end; i--) {
            if (buf[i-1] != 0) {
                return i;
            }
        }
        return end;
    }


    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() {
        return Objects.hash(id,type,value);

    }



    /**
     * @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(), -2L*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 {
                // use ISO-8601 timestamp format
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT);
                df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
                b.append(df.format(d));
            }
        } else if (type == Variant.VT_EMPTY || type == Variant.VT_NULL || value == null) {
            b.append("null");
        } else {
            b.append(value);

            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;
    }

}
