/**
 * 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 == "DecimalSparseDecimalDense">

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

        /* Before converting from a sparse representation to a dense representation
         * we need to convert it to an intermediate representation. In the sparse
         * representation we separate out the scale and the integer part of the decimal
         * and pad the scale part with additional zeroes for ease of performing arithmetic
         * operations. In the intermediate representation we strip out the extra zeroes and
         * combine the scale and integer part.
         */
        int[] intermediate = new int[in.nDecimalDigits - 1];

        int index = in.nDecimalDigits - 1;
        int actualDigits;

        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 paddedMask = (int) Math.pow(10, paddedDigits);

            /* We have a scale that does not completely occupy a decimal
             * digit, so we have padded zeroes to it for ease of arithmetic
             * Truncate the extra zeroes added and move the digits to the right
             */
            int temp = (in.getInteger(index, in.start, in.buffer)/paddedMask);
            index--;

            while(index >= 0) {

                int transferDigits = (in.getInteger(index, in.start, in.buffer) % (paddedMask));

                intermediate[index] = (int) (temp + (Math.pow(10, actualDigits) * transferDigits));

                temp = (in.getInteger(index, in.start, in.buffer)/(paddedMask));

                index--;
            }
        } else {

            /* If the scale does not exist or it perfectly fits within a decimal digit
             * then we have padded no zeroes, which means there can atmost be only 38 digits, which
             * need only 5 decimal digit to be stored, simply copy over the integers
             */
            for (int i = 1; i < in.nDecimalDigits; i++)
                intermediate[i - 1] = in.getInteger(i, in.start, in.buffer);

        }

        /* Now we have an intermediate representation in the array intermediate[]
         * Every number in the intermediate representation is base 1 billion number
         * To represent it we require only 30 bits, but every integer has 32 bits.
         * By shifting the bits around we can utilize the extra two bits on every
         * number and create a dense representation
         */

          /* Allocate a byte array */
          int size = (((intermediate.length - 1) * org.apache.drill.exec.util.DecimalUtility.integerSize) + 1);
          byte[] intermediateBytes = new byte[size];
          java.nio.ByteBuffer wrapper = java.nio.ByteBuffer.wrap(intermediateBytes);

          wrapper.put((byte) intermediate[0]);

          for (int i = 1; i < intermediate.length; i++) {
            wrapper.put(java.nio.ByteBuffer.allocate(org.apache.drill.exec.util.DecimalUtility.integerSize).putInt(intermediate[i]).array());
          }

          final int[] mask = {0x03, 0x0F, 0x3F, 0xFF};
          int maskIndex = 0;
          int shiftOrder = 2;

          // Start just after the last integer and shift bits to the right
          index = size - (org.apache.drill.exec.util.DecimalUtility.integerSize+ 1);

          while (index >= 0) {

              /* get the last bits that need to shifted to the next byte */
              byte shiftBits = (byte) ((intermediateBytes[index] & mask[maskIndex]) << (8 - shiftOrder));

              int shiftOrder1 = ((index % org.apache.drill.exec.util.DecimalUtility.integerSize) == 0) ? shiftOrder - 2 : shiftOrder;

              /* transfer the bits from the left to the right */
              intermediateBytes[index + 1] = (byte) (((intermediateBytes[index + 1] & 0xFF) >>> (shiftOrder1)) | shiftBits);

              index--;

              if ((index % org.apache.drill.exec.util.DecimalUtility.integerSize) == 0) {
                  /* We are on a border */
                  shiftOrder += 2;
                  maskIndex++;
              }
          }

          <#if (type.from == "Decimal28Sparse") && (type.to == "Decimal38Dense")>
          /* Decimal38Dense representation has four bytes more than that needed to
           * represent Decimal28Dense. So our first four bytes are empty in that scenario
           */
          int dstIndex = 4;
          <#else>
          int dstIndex = 0;
          </#if>

          // Set the bytes in the buffer
          out.buffer.setBytes(dstIndex, intermediateBytes, 1, (size - 1));
          out.setSign(in.getSign(in.start, in.buffer), out.start, out.buffer);
    }
}
</#if>
</#list>