/*
 * 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.carbondata.core.datastore.page;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.math.BigDecimal;

import org.apache.carbondata.core.datastore.page.encoding.ColumnPageEncoderMeta;
import org.apache.carbondata.core.metadata.datatype.DataType;
import org.apache.carbondata.core.metadata.datatype.DataTypes;
import org.apache.carbondata.core.util.ByteUtil;

/**
 * Represent a columnar data in one page for one column.
 */
public class SafeFixLengthColumnPage extends ColumnPage {

  // Only one of following fields will be used
  private byte[] byteData;
  private short[] shortData;
  private int[] intData;
  private long[] longData;
  private float[] floatData;
  private double[] doubleData;
  private byte[] shortIntData;
  private byte[][] fixedLengthData;
  private int totalLength;

  // total number of entries in array
  private int arrayElementCount = 0;

  SafeFixLengthColumnPage(ColumnPageEncoderMeta columnPageEncoderMeta, int pageSize) {
    super(columnPageEncoderMeta, pageSize);
  }

  /**
   * Set byte value at rowId
   */
  @Override
  public void putByte(int rowId, byte value) {
    ensureArraySize(rowId, DataTypes.BYTE);
    byteData[rowId] = value;
    arrayElementCount++;
    totalLength += DataTypes.BYTE.getSizeInBytes();
  }

  /**
   * Set short value at rowId
   */
  @Override
  public void putShort(int rowId, short value) {
    ensureArraySize(rowId, DataTypes.SHORT);
    shortData[rowId] = value;
    arrayElementCount++;
    totalLength += DataTypes.SHORT.getSizeInBytes();
  }

  /**
   * Set integer value at rowId
   */
  @Override
  public void putInt(int rowId, int value) {
    ensureArraySize(rowId, DataTypes.INT);
    intData[rowId] = value;
    arrayElementCount++;
    totalLength += DataTypes.INT.getSizeInBytes();
  }

  /**
   * Set long value at rowId
   */
  @Override
  public void putLong(int rowId, long value) {
    ensureArraySize(rowId, DataTypes.LONG);
    longData[rowId] = value;
    arrayElementCount++;
    totalLength += DataTypes.LONG.getSizeInBytes();
  }

  /**
   * Set double value at rowId
   */
  @Override
  public void putDouble(int rowId, double value) {
    ensureArraySize(rowId, DataTypes.DOUBLE);
    doubleData[rowId] = value;
    arrayElementCount++;
    totalLength += DataTypes.DOUBLE.getSizeInBytes();
  }

  /**
   * Set float value at rowId
   */
  @Override
  public void putFloat(int rowId, float value) {
    ensureArraySize(rowId, DataTypes.FLOAT);
    floatData[rowId] = value;
    arrayElementCount++;
    totalLength += DataTypes.FLOAT.getSizeInBytes();
  }

  /**
   * Set string value at rowId
   */
  @Override
  public void putBytes(int rowId, byte[] bytes) {
    ensureArraySize(rowId, DataTypes.BYTE_ARRAY);
    this.fixedLengthData[rowId] = bytes;
    arrayElementCount++;
    totalLength += bytes.length;
  }

  @Override
  public void putShortInt(int rowId, int value) {
    ensureArraySize(rowId, DataTypes.SHORT_INT);
    byte[] converted = ByteUtil.to3Bytes(value);
    System.arraycopy(converted, 0, shortIntData, rowId * 3, 3);
    arrayElementCount++;
    totalLength += DataTypes.SHORT_INT.getSizeInBytes();
  }

  @Override
  public void putBytes(int rowId, byte[] bytes, int offset, int length) {
    throw new UnsupportedOperationException(
        "invalid data type: " + columnPageEncoderMeta.getStoreDataType());
  }

  @Override
  public void putDecimal(int rowId, BigDecimal decimal) {
    throw new UnsupportedOperationException(
        "invalid data type: " + columnPageEncoderMeta.getStoreDataType());
  }

  @Override
  public byte[] getDecimalPage() {
    throw new UnsupportedOperationException(
        "invalid data type: " + columnPageEncoderMeta.getStoreDataType());
  }

  /**
   * Get byte value at rowId
   */
  @Override
  public byte getByte(int rowId) {
    return byteData[rowId];
  }

  /**
   * Get short value at rowId
   */
  @Override
  public short getShort(int rowId) {
    return shortData[rowId];
  }

  /**
   * Get short int value at rowId
   */
  @Override
  public int getShortInt(int rowId) {
    return ByteUtil.valueOf3Bytes(shortIntData, rowId * 3);
  }

  /**
   * Get int value at rowId
   */
  @Override
  public int getInt(int rowId) {
    return intData[rowId];
  }

  /**
   * Get long value at rowId
   */
  @Override
  public long getLong(int rowId) {
    return longData[rowId];
  }

  /**
   * Get float value at rowId
   */
  @Override
  public float getFloat(int rowId) {
    return floatData[rowId];
  }

  /**
   * Get double value at rowId
   */
  @Override
  public double getDouble(int rowId) {
    return doubleData[rowId];
  }

  @Override
  public BigDecimal getDecimal(int rowId) {
    throw new UnsupportedOperationException(
        "invalid data type: " + columnPageEncoderMeta.getStoreDataType());
  }

  @Override
  public byte[] getBytes(int rowId) {
    return this.fixedLengthData[rowId];
  }

  /**
   * Get byte value page
   */
  @Override
  public byte[] getBytePage() {
    return byteData;
  }

  /**
   * Get short value page
   */
  @Override
  public short[] getShortPage() {
    return shortData;
  }

  /**
   * Get short value page
   */
  @Override
  public byte[] getShortIntPage() {
    return shortIntData;
  }

  /**
   * Get int value page
   */
  @Override
  public int[] getIntPage() {
    return intData;
  }

  /**
   * Get long value page
   */
  @Override
  public long[] getLongPage() {
    return longData;
  }

  /**
   * Get float value page
   */
  @Override
  public float[] getFloatPage() {
    return floatData;
  }

  /**
   * Get double value page
   */
  @Override
  public double[] getDoublePage() {
    return doubleData;
  }

  /**
   * Get string page
   */
  @Override
  public byte[][] getByteArrayPage() {
    byte[][] data = new byte[arrayElementCount][];
    for (int i = 0; i < arrayElementCount; i++) {
      data[i] = fixedLengthData[i];
    }
    return data;
  }

  @Override
  public byte[] getLVFlattenedBytePage() {
    throw new UnsupportedOperationException(
        "invalid data type: " + columnPageEncoderMeta.getStoreDataType());
  }

  @Override
  public byte[] getComplexChildrenLVFlattenedBytePage(DataType dataType) throws IOException {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    DataOutputStream out = new DataOutputStream(stream);
    for (int i = 0; i < arrayElementCount; i++) {
      out.write(fixedLengthData[i]);
    }
    return stream.toByteArray();
  }

  @Override
  public byte[] getComplexParentFlattenedBytePage() {
    throw new UnsupportedOperationException("internal error");
  }

  /**
   * Set byte values to page
   */
  @Override
  public void setBytePage(byte[] byteData) {
    this.byteData = byteData;
  }

  /**
   * Set short values to page
   */
  @Override
  public void setShortPage(short[] shortData) {
    this.shortData = shortData;
  }

  /**
   * Set short values to page
   */
  @Override
  public void setShortIntPage(byte[] shortIntData) {
    this.shortIntData = shortIntData;
  }

  /**
   * Set int values to page
   */
  @Override
  public void setIntPage(int[] intData) {
    this.intData = intData;
  }

  /**
   * Set long values to page
   */
  @Override
  public void setLongPage(long[] longData) {
    this.longData = longData;
  }

  /**
   * Set float values to page
   */
  @Override
  public void setFloatPage(float[] floatData) {
    this.floatData = floatData;
  }

  /**
   * Set double value to page
   */
  @Override
  public void setDoublePage(double[] doubleData) {
    this.doubleData = doubleData;
  }

  /**
   * Set decimal values to page
   */
  @Override
  public void setByteArrayPage(byte[][] byteArray) {
    throw new UnsupportedOperationException(
        "invalid data type: " + columnPageEncoderMeta.getStoreDataType());
  }

  @Override
  public void freeMemory() {
    byteData = null;
    shortData = null;
    intData = null;
    longData = null;
    floatData = null;
    doubleData = null;
    shortIntData = null;
    fixedLengthData = null;
  }

  /**
   * apply encoding to page data
   * @param codec type of transformation
   */
  @Override
  public void convertValue(ColumnPageValueConverter codec) {
    if (columnPageEncoderMeta.getStoreDataType() == DataTypes.BYTE) {
      for (int i = 0; i < arrayElementCount; i++) {
        codec.encode(i, byteData[i]);
      }
    } else if (columnPageEncoderMeta.getStoreDataType() == DataTypes.SHORT) {
      for (int i = 0; i < arrayElementCount; i++) {
        codec.encode(i, shortData[i]);
      }
    } else if (columnPageEncoderMeta.getStoreDataType() == DataTypes.INT) {
      for (int i = 0; i < arrayElementCount; i++) {
        codec.encode(i, intData[i]);
      }
    } else if (columnPageEncoderMeta.getStoreDataType() == DataTypes.LONG) {
      for (int i = 0; i < arrayElementCount; i++) {
        codec.encode(i, longData[i]);
      }
    } else if (columnPageEncoderMeta.getStoreDataType() == DataTypes.FLOAT) {
      for (int i = 0; i < arrayElementCount; i++) {
        codec.encode(i, floatData[i]);
      }
    } else if (columnPageEncoderMeta.getStoreDataType() == DataTypes.DOUBLE) {
      for (int i = 0; i < arrayElementCount; i++) {
        codec.encode(i, doubleData[i]);
      }
    } else {
      throw new UnsupportedOperationException("not support value conversion on "
          + columnPageEncoderMeta.getStoreDataType() + " page");
    }
  }

  private void ensureArraySize(int requestSize, DataType dataType) {
    if (dataType == DataTypes.BYTE) {
      if (requestSize >= byteData.length) {
        byte[] newArray = new byte[arrayElementCount * 2];
        System.arraycopy(byteData, 0, newArray, 0, arrayElementCount);
        byteData = newArray;
      }
    } else if (dataType == DataTypes.SHORT) {
      if (requestSize >= shortData.length) {
        short[] newArray = new short[arrayElementCount * 2];
        System.arraycopy(shortData, 0, newArray, 0, arrayElementCount);
        shortData = newArray;
      }
    } else if (dataType == DataTypes.SHORT_INT) {
      if (requestSize >= shortIntData.length / 3) {
        byte[] newArray = new byte[arrayElementCount * 6];
        System.arraycopy(shortIntData, 0, newArray, 0, arrayElementCount * 3);
        shortIntData = newArray;
      }
    } else if (dataType == DataTypes.INT) {
      if (requestSize >= intData.length) {
        int[] newArray = new int[arrayElementCount * 2];
        System.arraycopy(intData, 0, newArray, 0, arrayElementCount);
        intData = newArray;
      }
    } else if (dataType == DataTypes.LONG) {
      if (requestSize >= longData.length) {
        long[] newArray = new long[arrayElementCount * 2];
        System.arraycopy(longData, 0, newArray, 0, arrayElementCount);
        longData = newArray;
      }
    } else if (dataType == DataTypes.FLOAT) {
      if (requestSize >= floatData.length) {
        float[] newArray = new float[arrayElementCount * 2];
        System.arraycopy(floatData, 0, newArray, 0, arrayElementCount);
        floatData = newArray;
      }
    } else if (dataType == DataTypes.DOUBLE) {
      if (requestSize >= doubleData.length) {
        double[] newArray = new double[arrayElementCount * 2];
        System.arraycopy(doubleData, 0, newArray, 0, arrayElementCount);
        doubleData = newArray;
      }
    } else if (dataType == DataTypes.BYTE_ARRAY) {
      if (fixedLengthData == null) {
        fixedLengthData = new byte[pageSize][];
      }
      if (requestSize >= fixedLengthData.length) {
        byte[][] newArray = new byte[arrayElementCount * 2][];
        int index = 0;
        for (byte[] data : fixedLengthData) {
          newArray[index++] = data;
        }
        fixedLengthData = newArray;
      }
    } else {
      throw new UnsupportedOperationException(
          "not support value conversion on " + dataType + " page");
    }
  }

  public int getActualRowCount() {
    return arrayElementCount;
  }

  @Override
  public long getPageLengthInBytes() {
    return totalLength;
  }
}
