/*******************************************************************************
 * Copyright (c) 2012, 2019 Ericsson, École Polytechnique de Montréal
 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License 2.0 which
 * accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Alexandre Montplaisir - Initial API and implementation
 *    Florian Wininger - Allow to change the size of a interval
 *    Patrick Tasse - Add message to exceptions
 *******************************************************************************/

package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Objects;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.datastore.core.encoding.HTVarInt;
import org.eclipse.tracecompass.datastore.core.serialization.ISafeByteBufferReader;
import org.eclipse.tracecompass.datastore.core.serialization.ISafeByteBufferWriter;
import org.eclipse.tracecompass.datastore.core.serialization.SafeByteBufferFactory;
import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.CustomStateValue;
import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;

/**
 * The interval component, which will be contained in a node of the History
 * Tree.
 *
 * @author Alexandre Montplaisir
 */
public final class HTInterval implements ITmfStateInterval {

    private static final Charset CHARSET = Charset.forName("UTF-8"); //$NON-NLS-1$

    private static final String errMsg = "Invalid interval data. Maybe your file is corrupt?"; //$NON-NLS-1$

    /* 'Byte' equivalent for state values types */
    private static final byte TYPE_NULL = -1;
    private static final byte TYPE_INTEGER = 0;
    private static final byte TYPE_STRING = 1;
    private static final byte TYPE_LONG = 2;
    private static final byte TYPE_DOUBLE = 3;
    private static final byte TYPE_CUSTOM = 20;

    private final long fStart;
    private final long fDuration;
    private final int fAttribute;
    private final @Nullable Object fStateValue;

    /** Number of bytes used by this interval when it is written to disk */
    private int fSizeOnDisk;

    /**
     * Standard constructor
     *
     * @param intervalStart
     *            Start time of the interval
     * @param intervalEnd
     *            End time of the interval
     * @param attribute
     *            Attribute (quark) to which the state represented by this
     *            interval belongs
     * @param value
     *            State value represented by this interval
     * @throws TimeRangeException
     *             If the start time or end time are invalid
     */
    public HTInterval(long intervalStart, long intervalEnd, int attribute,
            Object value) throws TimeRangeException {
        if (intervalStart > intervalEnd) {
            throw new TimeRangeException("Start:" + intervalStart + ", End:" + intervalEnd); //$NON-NLS-1$ //$NON-NLS-2$
        }

        fStart = intervalStart;
        fDuration = intervalEnd - intervalStart;
        fAttribute = attribute;
        fStateValue = (value instanceof TmfStateValue) ? ((ITmfStateValue) value).unboxValue() : value;
        fSizeOnDisk = computeSizeOnDisk(fStateValue, 0);
    }

    /**
     * Compute how much space (in bytes) an interval will take in its serialized
     * form on disk. This is dependent on its state value and the start time of
     * the node it is linked to.
     *
     * @param stateValue
     *            The state value
     * @param nodeStart
     *            The start time of the node the interval is linked to
     * @return The computed size on disk (with HTVarInt encoding)
     */
    private int computeSizeOnDisk(Object stateValue, long nodeStart) {
        /*
         * Minimum size is a 2x bytes (start), 2x bytes (duration), 1x int (attribute) and 1x
         * byte (value type).
         */
        int minSize = HTVarInt.getEncodedLengthLong(fStart - nodeStart) + HTVarInt.getEncodedLengthLong(fDuration) + Integer.BYTES + Byte.BYTES;

        if (stateValue == null) {
            return minSize;
        } else if (stateValue instanceof Integer) {
            return (minSize + Integer.BYTES);
        } else if (stateValue instanceof Long) {
            return (minSize + Long.BYTES);
        } else if (stateValue instanceof Double) {
            return (minSize + Double.BYTES);
        } else if (stateValue instanceof String) {
            String str = (String) stateValue;
            int strLength = str.getBytes(CHARSET).length;

            if (strLength > Short.MAX_VALUE) {
                throw new IllegalArgumentException("String is too long to be stored in state system: " + str); //$NON-NLS-1$
            }

            /*
             * String's length + 3 (2 bytes for size, 1 byte for \0 at the end)
             */
            return (minSize + strLength + 3);
        } else if (stateValue instanceof CustomStateValue) {
            /* Length of serialized value (short) + state value */
            return (minSize + Short.BYTES + ((CustomStateValue) stateValue).getSerializedSize());
        }
        /*
         * It's very important that we know how to write the state value in the
         * file!!
         */
        throw new IllegalStateException();
    }

    /**
     * "Faster" constructor for inner use only. When we build an interval when
     * reading it from disk (with {@link #readFrom}), we already know the size
     * of the strings entry, so there is no need to call
     * {@link #computeStringsEntrySize()} and do an extra copy.
     */
    private HTInterval(long intervalStart, long intervalEnd, int attribute,
            Object value, int size) throws TimeRangeException {
        if (intervalStart > intervalEnd) {
            throw new TimeRangeException("Start:" + intervalStart + ", End:" + intervalEnd); //$NON-NLS-1$ //$NON-NLS-2$
        }

        fStart = intervalStart;
        fDuration = intervalEnd - intervalStart;
        fAttribute = attribute;
        fStateValue = value;
        fSizeOnDisk = size;
    }

    /**
     * Reader factory method. Builds the interval using an already-allocated
     * ByteBuffer, which normally comes from a NIO FileChannel.
     *
     * The interval is just a start, end, attribute and value, this is the
     * layout of the HTInterval on disk
     * <ul>
     * <li>start (2-9 bytes)</li>
     * <li>end (2-9 bytes)</li>
     * <li>attribute (4 bytes)</li>
     * <li>sv type (1 byte)</li>
     * <li>sv ( 0 bytes for null, 4 for int , 8 for long and double, and the
     * length of the string +2 for strings (it's variable))</li>
     * </ul>
     *
     * @param buffer
     *            The ByteBuffer from which to read the information
     * @param nodeStart
     *             The start time of the node this interval is linked to
     * @return The interval object
     * @throws IOException
     *             If there was an error reading from the buffer
     */
    public static final HTInterval readFrom(ByteBuffer buffer, long nodeStart) throws IOException {
        Object value;

        int posStart = buffer.position();
        /* Read the Data Section entry */
        long intervalStart = HTVarInt.readLong(buffer) + nodeStart;
        long intervalEnd = HTVarInt.readLong(buffer) + intervalStart;
        int attribute = buffer.getInt();

        /* Read the 'type' of the value, then react accordingly */
        byte valueType = buffer.get();
        switch (valueType) {

        case TYPE_NULL:
            value = null;
            break;

        case TYPE_INTEGER:
            value = buffer.getInt();
            break;

        case TYPE_STRING: {
            /* the first short = the size to read */
            int valueSize = buffer.getShort();

            byte[] array = new byte[valueSize];
            buffer.get(array);
            value = new String(array, CHARSET);

            /* Confirm the 0'ed byte at the end */
            byte res = buffer.get();
            if (res != 0) {
                throw new IOException(errMsg);
            }
            break;
        }

        case TYPE_LONG:
            /* Go read the matching entry in the Strings section of the block */
            value = buffer.getLong();
            break;

        case TYPE_DOUBLE:
            /* Go read the matching entry in the Strings section of the block */
            value = buffer.getDouble();
            break;

        case TYPE_CUSTOM: {
            short valueSize = buffer.getShort();
            ISafeByteBufferReader safeBuffer = SafeByteBufferFactory.wrapReader(buffer, valueSize);
            value = CustomStateValue.readSerializedValue(safeBuffer);
            break;
        }
        default:
            /* Unknown data, better to not make anything up... */
            throw new IOException(errMsg);
        }

        try {
            return new HTInterval(intervalStart, intervalEnd, attribute, value, buffer.position() - posStart);
        } catch (TimeRangeException e) {
            throw new IOException(errMsg);
        }
    }

    /**
     * Antagonist of the previous constructor, write the Data entry
     * corresponding to this interval in a ByteBuffer (mapped to a block in the
     * history-file, hopefully)
     *
     * The interval is just a start, end, attribute and value, this is the
     * layout of the HTInterval on disk
     * <ul>
     * <li>start (2-9 bytes)</li>
     * <li>end (2-9 bytes)</li>
     * <li>attribute (4 bytes)</li>
     * <li>sv type (1 byte)</li>
     * <li>sv ( 0 bytes for null, 4 for int , 8 for long and double, and the
     * length of the string +2 for strings (it's variable))</li>
     * </ul>
     *
     * @param buffer
     *            The already-allocated ByteBuffer corresponding to a SHT Node
     */
    public void writeInterval(ByteBuffer buffer, long nodeStart) {
        HTVarInt.writeLong(buffer, fStart - nodeStart);
        HTVarInt.writeLong(buffer, fDuration);
        buffer.putInt(fAttribute);

        if (fStateValue != null) {
            @NonNull Object value = fStateValue;
            if (value instanceof Integer) {
                buffer.put(TYPE_INTEGER);
                buffer.putInt((int) value);
            } else if (value instanceof Long) {
                buffer.put(TYPE_LONG);
                buffer.putLong((long) value);
            } else if (value instanceof Double) {
                buffer.put(TYPE_DOUBLE);
                buffer.putDouble((double) value);
            } else if (value instanceof String) {
                buffer.put(TYPE_STRING);
                String string = (String) value;
                byte[] strArray = string.getBytes(CHARSET);

                /*
                 * Write the Strings entry (1st byte = size, then the bytes, then the 0). We
                 * have checked the string length at the constructor.
                 */
                buffer.putShort((short) strArray.length);
                buffer.put(strArray);
                buffer.put((byte) 0);
            } else if (value instanceof CustomStateValue) {
                buffer.put(TYPE_CUSTOM);
                int size = ((CustomStateValue) value).getSerializedSize();
                buffer.putShort((short) size);
                ISafeByteBufferWriter safeBuffer = SafeByteBufferFactory.wrapWriter(buffer, size);
                ((CustomStateValue) value).serialize(safeBuffer);
            } else {
                throw new IllegalStateException("Type: " + value.getClass() + " is not implemented in the state system"); //$NON-NLS-1$ //$NON-NLS-2$
            }
        } else {
            buffer.put(TYPE_NULL);
        }
    }

    @Override
    public long getStartTime() {
        return fStart;
    }

    @Override
    public long getEndTime() {
        return fStart + fDuration;
    }

    @Override
    public int getAttribute() {
        return fAttribute;
    }

    @Override
    public ITmfStateValue getStateValue() {
        return TmfStateValue.newValue(fStateValue);
    }

    @Override
    public Object getValue() {
        return fStateValue;
    }

    @Override
    public boolean intersects(long timestamp) {
        return (fStart <= timestamp && (fStart + fDuration) >= timestamp);
    }

    /**
     * Total serialized size of this interval
     *
     * @return The interval size
     */
    public int getSizeOnDisk() {
        return fSizeOnDisk;
    }

    /**
     * Computes serialized size of this interval with linked node start time
     *
     * @param nodeStart
     *            The start time of the node the interval is linked to
     * @return The size of the interval on disk using the HTVarInt encoding
     */
    public int getSizeOnDisk(long nodeStart) {
        return computeSizeOnDisk(fStateValue, nodeStart);
    }

    /**
     * @param sizeOnDisk the sizeOnDisk to set
     */
    public void setSizeOnDisk(int sizeOnDisk) {
        fSizeOnDisk = sizeOnDisk;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        HTInterval other = (HTInterval) obj;
        return (fStart == other.fStart &&
                fDuration == other.fDuration &&
                fAttribute == other.fAttribute &&
                Objects.equals(fStateValue, other.fStateValue));
    }

    @Override
    public int hashCode() {
        return Objects.hash(fStart, fDuration, fAttribute, fStateValue);
    }

    @Override
    public String toString() {
        /* Only for debug, should not be externalized */
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        sb.append(fStart);
        sb.append(", "); //$NON-NLS-1$
        sb.append(fStart + fDuration);
        sb.append(']');

        sb.append(", attribute = "); //$NON-NLS-1$
        sb.append(fAttribute);

        sb.append(", value = "); //$NON-NLS-1$
        sb.append(String.valueOf(fStateValue));

        return sb.toString();
    }
}
