/**
 * 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 "Column.h"
#include "ColumnDecoder.h"

TimeColumn::TimeColumn(int32_t arrayOffset, int32_t positionCount,
                       const std::vector<int64_t> &values)
    : arrayOffset_(arrayOffset), positionCount_(positionCount),
      values_(values) {
  if (arrayOffset < 0)
    throw IoTDBException("arrayOffset is negative");
  if (positionCount < 0)
    throw IoTDBException("positionCount is negative");
  if (static_cast<int32_t>(values.size()) - arrayOffset < positionCount) {
    throw IoTDBException("values length is less than positionCount");
  }
}

TSDataType::TSDataType TimeColumn::getDataType() const {
  return TSDataType::INT64;
}
ColumnEncoding TimeColumn::getEncoding() const {
  return ColumnEncoding::Int64Array;
}

int64_t TimeColumn::getLong(int32_t position) const {
  return values_[position + arrayOffset_];
}

bool TimeColumn::mayHaveNull() const { return false; }
bool TimeColumn::isNull(int32_t position) const { return false; }
std::vector<bool> TimeColumn::isNulls() const { return {}; }

int32_t TimeColumn::getPositionCount() const { return positionCount_; }

int64_t TimeColumn::getStartTime() const { return values_[arrayOffset_]; }
int64_t TimeColumn::getEndTime() const {
  return values_[positionCount_ + arrayOffset_ - 1];
}

const std::vector<int64_t> &TimeColumn::getTimes() const { return values_; }
std::vector<int64_t> TimeColumn::getLongs() const { return getTimes(); }

BinaryColumn::BinaryColumn(int32_t arrayOffset, int32_t positionCount,
                           const std::vector<bool> &valueIsNull,
                           const std::vector<std::shared_ptr<Binary>> &values)
    : arrayOffset_(arrayOffset), positionCount_(positionCount),
      valueIsNull_(valueIsNull), values_(values) {
  if (arrayOffset < 0)
    throw IoTDBException("arrayOffset is negative");
  if (positionCount < 0)
    throw IoTDBException("positionCount is negative");
  if (static_cast<int32_t>(values.size()) - arrayOffset < positionCount) {
    throw IoTDBException("values length is less than positionCount");
  }
  if (!valueIsNull.empty() &&
      static_cast<int32_t>(valueIsNull.size()) - arrayOffset < positionCount) {
    throw IoTDBException("isNull length is less than positionCount");
  }
}

TSDataType::TSDataType BinaryColumn::getDataType() const {
  return TSDataType::TSDataType::TEXT;
}
ColumnEncoding BinaryColumn::getEncoding() const {
  return ColumnEncoding::BinaryArray;
}

std::shared_ptr<Binary> BinaryColumn::getBinary(int32_t position) const {
  return values_[position + arrayOffset_];
}

std::vector<std::shared_ptr<Binary>> BinaryColumn::getBinaries() const {
  return values_;
}

bool BinaryColumn::mayHaveNull() const { return !valueIsNull_.empty(); }

bool BinaryColumn::isNull(int32_t position) const {
  return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_];
}

std::vector<bool> BinaryColumn::isNulls() const {
  if (!valueIsNull_.empty())
    return valueIsNull_;

  std::vector<bool> result(positionCount_, false);
  return result;
}

int32_t BinaryColumn::getPositionCount() const { return positionCount_; }

IntColumn::IntColumn(int32_t arrayOffset, int32_t positionCount,
                     const std::vector<bool> &valueIsNull,
                     const std::vector<int32_t> &values)
    : arrayOffset_(arrayOffset), positionCount_(positionCount),
      valueNull_(valueIsNull), values_(values) {
  if (arrayOffset < 0)
    throw IoTDBException("arrayOffset is negative");
  if (positionCount < 0)
    throw IoTDBException("positionCount is negative");
  if (static_cast<int32_t>(values.size()) - arrayOffset < positionCount) {
    throw IoTDBException("values length is less than positionCount");
  }
  if (!valueIsNull.empty() &&
      static_cast<int32_t>(valueIsNull.size()) - arrayOffset < positionCount) {
    throw IoTDBException("isNull length is less than positionCount");
  }
}

TSDataType::TSDataType IntColumn::getDataType() const {
  return TSDataType::INT32;
}
ColumnEncoding IntColumn::getEncoding() const {
  return ColumnEncoding::Int32Array;
}

int32_t IntColumn::getInt(int32_t position) const {
  return values_[position + arrayOffset_];
}

int64_t IntColumn::getLong(int32_t position) const {
  return values_[position + arrayOffset_];
}

float IntColumn::getFloat(int32_t position) const {
  return values_[position + arrayOffset_];
}

double IntColumn::getDouble(int32_t position) const {
  return values_[position + arrayOffset_];
}

std::vector<int32_t> IntColumn::getInts() const { return values_; }

bool IntColumn::mayHaveNull() const { return !valueNull_.empty(); }

bool IntColumn::isNull(int32_t position) const {
  return !valueNull_.empty() && valueNull_[position + arrayOffset_];
}

std::vector<bool> IntColumn::isNulls() const {
  if (!valueNull_.empty())
    return valueNull_;

  std::vector<bool> result(positionCount_, false);
  return result;
}

int32_t IntColumn::getPositionCount() const { return positionCount_; }

FloatColumn::FloatColumn(int32_t arrayOffset, int32_t positionCount,
                         const std::vector<bool> &valueIsNull,
                         const std::vector<float> &values)
    : arrayOffset_(arrayOffset), positionCount_(positionCount),
      valueIsNull_(valueIsNull), values_(values) {
  if (arrayOffset < 0)
    throw IoTDBException("arrayOffset is negative");
  if (positionCount < 0)
    throw IoTDBException("positionCount is negative");
  if (static_cast<int32_t>(values.size()) - arrayOffset < positionCount) {
    throw IoTDBException("values length is less than positionCount");
  }
  if (!valueIsNull.empty() &&
      static_cast<int32_t>(valueIsNull.size()) - arrayOffset < positionCount) {
    throw IoTDBException("isNull length is less than positionCount");
  }
}

TSDataType::TSDataType FloatColumn::getDataType() const {
  return TSDataType::TSDataType::FLOAT;
}
ColumnEncoding FloatColumn::getEncoding() const {
  return ColumnEncoding::Int32Array;
}

float FloatColumn::getFloat(int32_t position) const {
  return values_[position + arrayOffset_];
}

double FloatColumn::getDouble(int32_t position) const {
  return values_[position + arrayOffset_];
}

std::vector<float> FloatColumn::getFloats() const { return values_; }

bool FloatColumn::mayHaveNull() const { return !valueIsNull_.empty(); }

bool FloatColumn::isNull(int32_t position) const {
  return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_];
}

std::vector<bool> FloatColumn::isNulls() const {
  if (!valueIsNull_.empty())
    return valueIsNull_;

  std::vector<bool> result(positionCount_, false);
  return result;
}

int32_t FloatColumn::getPositionCount() const { return positionCount_; }

LongColumn::LongColumn(int32_t arrayOffset, int32_t positionCount,
                       const std::vector<bool> &valueIsNull,
                       const std::vector<int64_t> &values)
    : arrayOffset_(arrayOffset), positionCount_(positionCount),
      valueIsNull_(valueIsNull), values_(values) {
  if (arrayOffset < 0)
    throw IoTDBException("arrayOffset is negative");
  if (positionCount < 0)
    throw IoTDBException("positionCount is negative");
  if (static_cast<int32_t>(values.size()) - arrayOffset < positionCount) {
    throw IoTDBException("values length is less than positionCount");
  }
  if (!valueIsNull.empty() &&
      static_cast<int32_t>(valueIsNull.size()) - arrayOffset < positionCount) {
    throw IoTDBException("isNull length is less than positionCount");
  }
}

TSDataType::TSDataType LongColumn::getDataType() const {
  return TSDataType::TSDataType::INT64;
}
ColumnEncoding LongColumn::getEncoding() const {
  return ColumnEncoding::Int64Array;
}

int64_t LongColumn::getLong(int32_t position) const {
  return values_[position + arrayOffset_];
}

double LongColumn::getDouble(int32_t position) const {
  return values_[position + arrayOffset_];
}

std::vector<int64_t> LongColumn::getLongs() const { return values_; }

bool LongColumn::mayHaveNull() const { return !valueIsNull_.empty(); }

bool LongColumn::isNull(int32_t position) const {
  return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_];
}

std::vector<bool> LongColumn::isNulls() const {
  if (!valueIsNull_.empty())
    return valueIsNull_;

  std::vector<bool> result(positionCount_, false);
  return result;
}

int32_t LongColumn::getPositionCount() const { return positionCount_; }

DoubleColumn::DoubleColumn(int32_t arrayOffset, int32_t positionCount,
                           const std::vector<bool> &valueIsNull,
                           const std::vector<double> &values)
    : arrayOffset_(arrayOffset), positionCount_(positionCount),
      valueIsNull_(valueIsNull), values_(values) {
  if (arrayOffset < 0)
    throw IoTDBException("arrayOffset is negative");
  if (positionCount < 0)
    throw IoTDBException("positionCount is negative");
  if (static_cast<int32_t>(values.size()) - arrayOffset < positionCount) {
    throw IoTDBException("values length is less than positionCount");
  }
  if (!valueIsNull.empty() &&
      static_cast<int32_t>(valueIsNull.size()) - arrayOffset < positionCount) {
    throw IoTDBException("isNull length is less than positionCount");
  }
}

TSDataType::TSDataType DoubleColumn::getDataType() const {
  return TSDataType::TSDataType::DOUBLE;
}
ColumnEncoding DoubleColumn::getEncoding() const {
  return ColumnEncoding::Int64Array;
}

double DoubleColumn::getDouble(int32_t position) const {
  return values_[position + arrayOffset_];
}

std::vector<double> DoubleColumn::getDoubles() const { return values_; }

bool DoubleColumn::mayHaveNull() const { return !valueIsNull_.empty(); }

bool DoubleColumn::isNull(int32_t position) const {
  return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_];
}

std::vector<bool> DoubleColumn::isNulls() const {
  if (!valueIsNull_.empty())
    return valueIsNull_;

  std::vector<bool> result(positionCount_, false);
  return result;
}

int32_t DoubleColumn::getPositionCount() const { return positionCount_; }

BooleanColumn::BooleanColumn(int32_t arrayOffset, int32_t positionCount,
                             const std::vector<bool> &valueIsNull,
                             const std::vector<bool> &values)
    : arrayOffset_(arrayOffset), positionCount_(positionCount),
      valueIsNull_(valueIsNull), values_(values) {
  if (arrayOffset < 0)
    throw IoTDBException("arrayOffset is negative");
  if (positionCount < 0)
    throw IoTDBException("positionCount is negative");
  if (static_cast<int32_t>(values.size()) - arrayOffset < positionCount) {
    throw IoTDBException("values length is less than positionCount");
  }
  if (!valueIsNull.empty() &&
      static_cast<int32_t>(valueIsNull.size()) - arrayOffset < positionCount) {
    throw IoTDBException("isNull length is less than positionCount");
  }
}

TSDataType::TSDataType BooleanColumn::getDataType() const {
  return TSDataType::TSDataType::BOOLEAN;
}
ColumnEncoding BooleanColumn::getEncoding() const {
  return ColumnEncoding::ByteArray;
}

bool BooleanColumn::getBoolean(int32_t position) const {
  return values_[position + arrayOffset_];
}

std::vector<bool> BooleanColumn::getBooleans() const { return values_; }

bool BooleanColumn::mayHaveNull() const { return !valueIsNull_.empty(); }

bool BooleanColumn::isNull(int32_t position) const {
  return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_];
}

std::vector<bool> BooleanColumn::isNulls() const {
  if (!valueIsNull_.empty())
    return valueIsNull_;

  std::vector<bool> result(positionCount_, false);
  return result;
}

int32_t BooleanColumn::getPositionCount() const { return positionCount_; }

RunLengthEncodedColumn::RunLengthEncodedColumn(std::shared_ptr<Column> value,
                                               int32_t positionCount)
    : value_(value), positionCount_(positionCount) {
  if (!value)
    throw IoTDBException("value is null");
  if (value->getPositionCount() != 1) {
    throw IoTDBException("Expected value to contain a single position");
  }
  if (positionCount < 0)
    throw IoTDBException("positionCount is negative");
}

std::shared_ptr<Column> RunLengthEncodedColumn::getValue() const {
  return value_;
}

TSDataType::TSDataType RunLengthEncodedColumn::getDataType() const {
  return value_->getDataType();
}
ColumnEncoding RunLengthEncodedColumn::getEncoding() const {
  return ColumnEncoding::Rle;
}

bool RunLengthEncodedColumn::getBoolean(int32_t position) const {
  return value_->getBoolean(0);
}

int32_t RunLengthEncodedColumn::getInt(int32_t position) const {
  return value_->getInt(0);
}

int64_t RunLengthEncodedColumn::getLong(int32_t position) const {
  return value_->getLong(0);
}

float RunLengthEncodedColumn::getFloat(int32_t position) const {
  return value_->getFloat(0);
}

double RunLengthEncodedColumn::getDouble(int32_t position) const {
  return value_->getDouble(0);
}

std::shared_ptr<Binary>
RunLengthEncodedColumn::getBinary(int32_t position) const {
  return value_->getBinary(0);
}

std::vector<bool> RunLengthEncodedColumn::getBooleans() const {
  bool v = value_->getBoolean(0);
  return std::vector<bool>(positionCount_, v);
}

std::vector<int32_t> RunLengthEncodedColumn::getInts() const {
  int32_t v = value_->getInt(0);
  return std::vector<int32_t>(positionCount_, v);
}

std::vector<int64_t> RunLengthEncodedColumn::getLongs() const {
  int64_t v = value_->getLong(0);
  return std::vector<int64_t>(positionCount_, v);
}

std::vector<float> RunLengthEncodedColumn::getFloats() const {
  float v = value_->getFloat(0);
  return std::vector<float>(positionCount_, v);
}

std::vector<double> RunLengthEncodedColumn::getDoubles() const {
  double v = value_->getDouble(0);
  return std::vector<double>(positionCount_, v);
}

std::vector<std::shared_ptr<Binary>>
RunLengthEncodedColumn::getBinaries() const {
  auto v = value_->getBinary(0);
  return std::vector<std::shared_ptr<Binary>>(positionCount_, v);
}

bool RunLengthEncodedColumn::mayHaveNull() const {
  return value_->mayHaveNull();
}

bool RunLengthEncodedColumn::isNull(int32_t position) const {
  return value_->isNull(0);
}

std::vector<bool> RunLengthEncodedColumn::isNulls() const {
  bool v = value_->isNull(0);
  return std::vector<bool>(positionCount_, v);
}

int32_t RunLengthEncodedColumn::getPositionCount() const {
  return positionCount_;
}
