/**
 * 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.
 */
<@pp.dropOutputFile />

<#list cast.types as type>
<#if type.major == "DecimalDenseDecimalSparse">

<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gcast/Cast${type.from}${type.to}.java" />

<#include "/@includes/license.ftl" />

package org.apache.drill.exec.expr.fn.impl.gcast;

<#include "/@includes/vv_imports.ftl" />

import org.apache.drill.exec.expr.DrillSimpleFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
import org.apache.drill.exec.expr.annotations.Output;
import org.apache.drill.exec.expr.annotations.Param;
import org.apache.drill.exec.expr.holders.*;
import org.apache.drill.exec.record.RecordBatch;
import org.apache.drill.exec.expr.annotations.Workspace;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.DrillBuf;

import java.nio.ByteBuffer;

@SuppressWarnings("unused")
@FunctionTemplate(name = "cast${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.DECIMAL_CAST, nulls=NullHandling.NULL_IF_NULL)
public class Cast${type.from}${type.to} implements DrillSimpleFunc{

    @Param ${type.from}Holder in;
    @Inject DrillBuf buffer;
    @Param BigIntHolder precision;
    @Param BigIntHolder scale;
    @Output ${type.to}Holder out;

    public void setup() {
        int size = (${type.arraySize} * (org.apache.drill.exec.util.DecimalUtility.integerSize));
        buffer = buffer.reallocIfNeeded(size);
    }

    public void eval() {
        out.buffer = buffer;
        out.start = 0;

        // Re initialize the buffer everytime
        for (int i = 0; i < ${type.arraySize}; i++) {
            out.setInteger(i, 0, out.start, out.buffer);
        }
        out.scale = (int) scale.value;
        out.precision = (int) precision.value;
        out.setSign(in.getSign(in.start, in.buffer), out.start, out.buffer);

        /* We store base 1 Billion integers in our representation, which requires
         * 30 bits, but a typical integer requires 32 bits. In our dense representation
         * we shift bits around to utilize the two available bits, to get back to our sparse
         * representation rearrange the bits so that we use 32 bits represent the digits.
         */

        byte[] intermediateBytes = new byte[(in.nDecimalDigits * org.apache.drill.exec.util.DecimalUtility.integerSize) + 1];

        int[] mask = {0x03, 0x0F, 0x3F, 0xFF};
        int[] reverseMask = {0xFC, 0xF0, 0xC0, 0x00};

        <#if (type.from == "Decimal38Dense")>
        int maskIndex = 0;
        int shiftOrder = 6;
        byte shiftBits = 0x00;
        intermediateBytes[0] = (byte) (in.buffer.getByte(0) & 0x7F);
        <#elseif (type.from == "Decimal28Dense")>
        int maskIndex = 1;
        int shiftOrder = 4;
        byte shiftBits = (byte) ((in.buffer.getByte(0) & 0x03) << shiftOrder);
        intermediateBytes[0] = (byte) (((in.buffer.getByte(0) & 0x3C) & 0xFF) >>> 2);
        </#if>

        int intermediateIndex = 1;
        int inputIndex = in.start + 1;

        while (intermediateIndex < in.WIDTH) {

            intermediateBytes[intermediateIndex] = (byte) ((shiftBits) | (((in.buffer.getByte(inputIndex) & reverseMask[maskIndex]) & 0xFF) >>> (8 - shiftOrder)));

            shiftBits = (byte) ((in.buffer.getByte(inputIndex) & mask[maskIndex]) << shiftOrder);

            inputIndex++;
            intermediateIndex++;

            if (((intermediateIndex - 1) % org.apache.drill.exec.util.DecimalUtility.integerSize) == 0) {
                shiftBits = (byte) ((shiftBits & 0xFF) >>> 2);
                maskIndex++;
                shiftOrder -= 2;
            }

        }

        /* copy the last byte */
        intermediateBytes[intermediateIndex] = shiftBits;

        /* We have shifted the bits around and now each digit is represented by 32 digits
         * Now we transfer the bytes into a integer array and separate out the scale and
         * integer part of the decimal. Also pad the scale part with zeroes if needed
         */
        int[] intermediate = new int[(intermediateBytes.length/org.apache.drill.exec.util.DecimalUtility.integerSize) + 1];

        java.nio.ByteBuffer wrapper = java.nio.ByteBuffer.wrap(intermediateBytes);
        intermediate[0] = wrapper.get(0);

        int intermediateIdx = 1;

        for (int i = 1; i < intermediate.length; i++) {
            intermediate[i] = wrapper.getInt(intermediateIdx);
            intermediateIdx += 4;
        }

        int actualDigits;
        int srcIndex = intermediate.length - 1;
        int dstIndex = out.nDecimalDigits - 1;

        // break the scale and integer part and pad zeroes
        if (in.scale > 0 && (actualDigits = (in.scale % org.apache.drill.exec.util.DecimalUtility.MAX_DIGITS)) > 0) {

            int paddedDigits = org.apache.drill.exec.util.DecimalUtility.MAX_DIGITS - actualDigits;
            int padding = (int) (Math.pow(10, paddedDigits));
            int transferDigitMask = (int) (Math.pow(10, actualDigits));

            /* copy the remaining scale over to the last deciml digit */
            out.setInteger(dstIndex, ((intermediate[srcIndex] % transferDigitMask) * (padding)), out.start, out.buffer);
            dstIndex--;

            while (srcIndex > 0) {
                out.setInteger(dstIndex, ((intermediate[srcIndex]/transferDigitMask) + ((intermediate[srcIndex - 1] % transferDigitMask) * padding)), out.start, out.buffer);

                dstIndex--;
                srcIndex--;
            }

            out.setInteger(dstIndex, (intermediate[0]/transferDigitMask), out.start, out.buffer);
        } else {
            for (; srcIndex >= 0; srcIndex--, dstIndex--)
                out.setInteger(dstIndex, intermediate[srcIndex], out.start, out.buffer);
        }
    }
}
</#if>
</#list>