/* ====================================================================
   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.ss.formula.constant;

import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.StringUtil;

/**
 * To support Constant Values (2.5.7) as required by the CRN record.
 * This class is also used for two dimensional arrays which are encoded by
 * EXTERNALNAME (5.39) records and Array tokens.
 */
public final class ConstantValueParser {
    // note - these (non-combinable) enum values are sparse.
    private static final int TYPE_EMPTY = 0;
    private static final int TYPE_NUMBER = 1;
    private static final int TYPE_STRING = 2;
    private static final int TYPE_BOOLEAN = 4;
    private static final int TYPE_ERROR_CODE = 16; // TODO - update OOO document to include this value

    private static final int TRUE_ENCODING = 1;
    private static final int FALSE_ENCODING = 0;

    // TODO - is this the best way to represent 'EMPTY'?
    private static final Object EMPTY_REPRESENTATION = null;

    private ConstantValueParser() {
        // no instances of this class
    }

    public static Object[] parse(LittleEndianInput in, int nValues) {
        Object[] result = new Object[nValues];
        for (int i = 0; i < result.length; i++) {
            result[i] = readAConstantValue(in);
        }
        return result;
    }

    private static Object readAConstantValue(LittleEndianInput in) {
        byte grbit = in.readByte();
        switch(grbit) {
            case TYPE_EMPTY:
                in.readLong(); // 8 byte 'not used' field
                return EMPTY_REPRESENTATION;
            case TYPE_NUMBER:
                return in.readDouble();
            case TYPE_STRING:
                return StringUtil.readUnicodeString(in);
            case TYPE_BOOLEAN:
                return readBoolean(in);
            case TYPE_ERROR_CODE:
                int errCode = in.readUShort();
                // next 6 bytes are unused
                in.readUShort();
                in.readInt();
                return ErrorConstant.valueOf(errCode);
        }
        throw new RuntimeException("Unknown grbit value (" + grbit + ")");
    }

    private static Object readBoolean(LittleEndianInput in) {
        byte val = (byte)in.readLong(); // 7 bytes 'not used'
        switch(val) {
            case FALSE_ENCODING:
                return Boolean.FALSE;
            case TRUE_ENCODING:
                return Boolean.TRUE;
        }
        // Don't tolerate unusual boolean encoded values (unless it becomes evident that they occur)
        throw new RuntimeException("unexpected boolean encoding (" + val + ")");
    }

    public static int getEncodedSize(Object[] values) {
        // start with one byte 'type' code for each value
        int result = values.length;
        for (Object value : values) {
            result += getEncodedSize(value);
        }
        return result;
    }

    /**
     * @return encoded size without the 'type' code byte
     */
    private static int getEncodedSize(Object object) {
        if(object == EMPTY_REPRESENTATION) {
            return 8;
        }
        Class<?> cls = object.getClass();

        if(cls == Boolean.class || cls == Double.class || cls == ErrorConstant.class) {
            return 8;
        }
        String strVal = (String)object;
        return StringUtil.getEncodedSize(strVal);
    }

    public static void encode(LittleEndianOutput out, Object[] values) {
        for (Object value : values) {
            encodeSingleValue(out, value);
        }
    }

    private static void encodeSingleValue(LittleEndianOutput out, Object value) {
        if (value == EMPTY_REPRESENTATION) {
            out.writeByte(TYPE_EMPTY);
            out.writeLong(0L);
            return;
        }
        if (value instanceof Boolean) {
            Boolean bVal = ((Boolean)value);
            out.writeByte(TYPE_BOOLEAN);
            long longVal = bVal ? 1L : 0L;
            out.writeLong(longVal);
            return;
        }
        if (value instanceof Double) {
            Double dVal = (Double) value;
            out.writeByte(TYPE_NUMBER);
            out.writeDouble(dVal);
            return;
        }
        if (value instanceof String) {
            String val = (String) value;
            out.writeByte(TYPE_STRING);
            StringUtil.writeUnicodeString(out, val);
            return;
        }
        if (value instanceof ErrorConstant) {
            ErrorConstant ecVal = (ErrorConstant) value;
            out.writeByte(TYPE_ERROR_CODE);
            long longVal = ecVal.getErrorCode();
            out.writeLong(longVal);
            return;
        }

        throw new IllegalStateException("Unexpected value type (" + value.getClass().getName() + "'");
    }
}
