/**
 * 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.
 */

#include "ColumnDecoder.h"

#include "Column.h"

std::vector<bool> deserializeNullIndicators(MyStringBuffer &buffer,
                                            int32_t positionCount) {
  uint8_t mayHaveNullByte = buffer.getChar();

  bool mayHaveNull = mayHaveNullByte != 0;
  if (!mayHaveNull) {
    return {};
  }

  return deserializeBooleanArray(buffer, positionCount);
}

std::vector<bool> deserializeBooleanArray(MyStringBuffer &buffer,
                                          int32_t size) {
  const int32_t packedSize = (size + 7) / 8;
  std::vector<uint8_t> packedBytes(packedSize);
  for (int i = 0; i < packedSize; i++) {
    packedBytes[i] = buffer.getChar();
  }

  std::vector<bool> output(size);
  int currentByte = 0;
  const int fullGroups = size & ~0b111;

  for (int pos = 0; pos < fullGroups; pos += 8) {
    const uint8_t b = packedBytes[currentByte++];
    output[pos + 0] = (b & 0b10000000) != 0;
    output[pos + 1] = (b & 0b01000000) != 0;
    output[pos + 2] = (b & 0b00100000) != 0;
    output[pos + 3] = (b & 0b00010000) != 0;
    output[pos + 4] = (b & 0b00001000) != 0;
    output[pos + 5] = (b & 0b00000100) != 0;
    output[pos + 6] = (b & 0b00000010) != 0;
    output[pos + 7] = (b & 0b00000001) != 0;
  }

  if ((size & 0b111) > 0) {
    const uint8_t b = packedBytes.back();
    uint8_t mask = 0b10000000;

    for (int pos = fullGroups; pos < size; pos++) {
      output[pos] = (b & mask) != 0;
      mask >>= 1;
    }
  }

  return output;
}

std::unique_ptr<Column>
BaseColumnDecoder::readColumn(MyStringBuffer &buffer,
                              TSDataType::TSDataType dataType,
                              int32_t positionCount) {
  return nullptr;
}

std::unique_ptr<Column>
Int32ArrayColumnDecoder::readColumn(MyStringBuffer &buffer,
                                    TSDataType::TSDataType dataType,
                                    int32_t positionCount) {
  auto nullIndicators = deserializeNullIndicators(buffer, positionCount);

  switch (dataType) {
  case TSDataType::INT32:
  case TSDataType::DATE: {
    std::vector<int32_t> intValues(positionCount);
    for (int32_t i = 0; i < positionCount; i++) {
      if (!nullIndicators.empty() && nullIndicators[i])
        continue;
      intValues[i] = buffer.getInt();
    }
    return std::unique_ptr<IntColumn>(
        new IntColumn(0, positionCount, nullIndicators, intValues));
  }
  case TSDataType::FLOAT: {
    std::vector<float> floatValues(positionCount);
    for (int32_t i = 0; i < positionCount; i++) {
      if (!nullIndicators.empty() && nullIndicators[i])
        continue;
      floatValues[i] = buffer.getFloat();
    }
    return std::unique_ptr<FloatColumn>(
        new FloatColumn(0, positionCount, nullIndicators, floatValues));
  }
  default:
    throw IoTDBException("Invalid data type for Int32ArrayColumnDecoder");
  }
}

std::unique_ptr<Column>
Int64ArrayColumnDecoder::readColumn(MyStringBuffer &buffer,
                                    TSDataType::TSDataType dataType,
                                    int32_t positionCount) {
  auto nullIndicators = deserializeNullIndicators(buffer, positionCount);

  switch (dataType) {
  case TSDataType::INT64:
  case TSDataType::TIMESTAMP: {
    std::vector<int64_t> values(positionCount);
    for (int32_t i = 0; i < positionCount; i++) {
      if (!nullIndicators.empty() && nullIndicators[i])
        continue;
      values[i] = buffer.getInt64();
    }
    return std::unique_ptr<LongColumn>(
        new LongColumn(0, positionCount, nullIndicators, values));
  }
  case TSDataType::DOUBLE: {
    std::vector<double> values(positionCount);
    for (int32_t i = 0; i < positionCount; i++) {
      if (!nullIndicators.empty() && nullIndicators[i])
        continue;
      values[i] = buffer.getDouble();
    }
    return std::unique_ptr<DoubleColumn>(
        new DoubleColumn(0, positionCount, nullIndicators, values));
  }
  default:
    throw IoTDBException("Invalid data type for Int64ArrayColumnDecoder");
  }
}

std::unique_ptr<Column>
ByteArrayColumnDecoder::readColumn(MyStringBuffer &buffer,
                                   TSDataType::TSDataType dataType,
                                   int32_t positionCount) {
  if (dataType != TSDataType::BOOLEAN) {
    throw IoTDBException("Invalid data type for ByteArrayColumnDecoder");
  }

  auto nullIndicators = deserializeNullIndicators(buffer, positionCount);
  auto values = deserializeBooleanArray(buffer, positionCount);
  return std::unique_ptr<BooleanColumn>(
      new BooleanColumn(0, positionCount, nullIndicators, values));
}

std::unique_ptr<Column>
BinaryArrayColumnDecoder::readColumn(MyStringBuffer &buffer,
                                     TSDataType::TSDataType dataType,
                                     int32_t positionCount) {
  if (dataType != TSDataType::TEXT) {
    throw IoTDBException("Invalid data type for BinaryArrayColumnDecoder");
  }

  auto nullIndicators = deserializeNullIndicators(buffer, positionCount);
  std::vector<std::shared_ptr<Binary>> values(positionCount);

  for (int32_t i = 0; i < positionCount; i++) {
    if (!nullIndicators.empty() && nullIndicators[i])
      continue;

    int32_t length = buffer.getInt();
    if (length < 0) {
      throw IoTDBException("BinaryArrayColumnDecoder: negative TEXT length");
    }

    std::vector<uint8_t> value(length);
    for (int32_t j = 0; j < length; j++) {
      value[j] = buffer.getChar();
    }

    values[i] = std::make_shared<Binary>(value);
  }

  return std::unique_ptr<BinaryColumn>(
      new BinaryColumn(0, positionCount, nullIndicators, values));
}

std::unique_ptr<Column>
RunLengthColumnDecoder::readColumn(MyStringBuffer &buffer,
                                   TSDataType::TSDataType dataType,
                                   int32_t positionCount) {
  uint8_t encodingByte = buffer.getChar();

  auto columnEncoding = static_cast<ColumnEncoding>(encodingByte);
  auto decoder = getColumnDecoder(columnEncoding);

  auto column = decoder->readColumn(buffer, dataType, 1);
  if (!column) {
    throw IoTDBException("Failed to read inner column");
  }
  return std::unique_ptr<RunLengthEncodedColumn>(
      new RunLengthEncodedColumn(move(column), positionCount));
}
