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

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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 static org.apache.logging.log4j.util.Unbox.box;

/**
 * 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 Logger LOG = LogManager.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(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.atWarn().withThrowable(e).log("can't serialize string");
            }

            // 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 Date) {
            Date d = (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.atWarn().log("Can't decode id {}", box(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;
    }

}
