/**
* 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 "SessionDataSet.h"

#include <stdexcept>

#include "IoTDBRpcDataSet.h"
#include "SessionDataSetFactory.h"

using namespace std;

struct SessionDataSet::Impl {
  std::shared_ptr<IoTDBRpcDataSet> iotdbRpcDataSet_;
};

std::unique_ptr<SessionDataSet>
createSessionDataSet(const std::string& sql, const std::vector<std::string>& columnNameList,
                     const std::vector<std::string>& columnTypeList,
                     const std::map<std::string, int32_t>& columnNameIndex, int64_t queryId,
                     int64_t statementId, std::shared_ptr<IClientRPCServiceClient> client,
                     int64_t sessionId, const std::vector<std::string>& queryResult,
                     bool ignoreTimestamp, int64_t timeout, bool moreData, int32_t fetchSize,
                     const std::string& zoneId, int32_t timeFactor,
                     std::vector<int32_t>& columnIndex2TsBlockColumnIndexList) {
  auto dataSet = std::unique_ptr<SessionDataSet>(new SessionDataSet());
  dataSet->impl_ = std::unique_ptr<SessionDataSet::Impl>(new SessionDataSet::Impl());
  dataSet->impl_->iotdbRpcDataSet_ = std::make_shared<IoTDBRpcDataSet>(
      sql, columnNameList, columnTypeList, columnNameIndex, ignoreTimestamp, moreData, queryId,
      statementId, client, sessionId, queryResult, fetchSize, timeout, zoneId,
      IoTDBRpcDataSet::DEFAULT_TIME_FORMAT, timeFactor, columnIndex2TsBlockColumnIndexList);
  return dataSet;
}

RowRecord::RowRecord(int64_t timestamp) {
  this->timestamp = timestamp;
}

RowRecord::RowRecord(int64_t timestamp, const std::vector<Field>& fields)
    : timestamp(timestamp), fields(fields) {}

RowRecord::RowRecord(const std::vector<Field>& fields) : timestamp(-1), fields(fields) {}

RowRecord::RowRecord() {
  this->timestamp = -1;
}

void RowRecord::addField(const Field& f) {
  this->fields.push_back(f);
}

std::string RowRecord::toString() {
  std::string ret;
  if (this->timestamp != -1) {
    ret.append(std::to_string(timestamp));
    ret.append("\t");
  }
  for (size_t i = 0; i < fields.size(); i++) {
    if (i != 0) {
      ret.append("\t");
    }
    const Field& f = fields[i];
    switch (f.dataType) {
    case TSDataType::BOOLEAN:
      if (f.isNull()) {
        ret.append("null");
      } else {
        ret.append(f.boolV.value() ? "true" : "false");
      }
      break;
    case TSDataType::INT32:
      if (f.isNull()) {
        ret.append("null");
      } else {
        ret.append(std::to_string(f.intV.value()));
      }
      break;
    case TSDataType::DATE:
      if (f.isNull()) {
        ret.append("null");
      } else {
        ret.append(f.dateV.value().toIsoExtendedString());
      }
      break;
    case TSDataType::TIMESTAMP:
    case TSDataType::INT64:
      if (f.isNull()) {
        ret.append("null");
      } else {
        ret.append(std::to_string(f.longV.value()));
      }
      break;
    case TSDataType::FLOAT:
      if (f.isNull()) {
        ret.append("null");
      } else {
        ret.append(std::to_string(f.floatV.value()));
      }
      break;
    case TSDataType::DOUBLE:
      if (f.isNull()) {
        ret.append("null");
      } else {
        ret.append(std::to_string(f.doubleV.value()));
      }
      break;
    case TSDataType::BLOB:
    case TSDataType::STRING:
    case TSDataType::TEXT:
      if (f.isNull()) {
        ret.append("null");
      } else {
        ret.append(f.stringV.value());
      }
      break;
    case TSDataType::OBJECT:
      if (!f.stringV.is_initialized()) {
        ret.append("null");
      } else {
        ret.append(f.stringV.value());
      }
      break;
    default:
      break;
    }
  }
  ret.append("\n");
  return ret;
}

SessionDataSet::~SessionDataSet() = default;

bool SessionDataSet::hasNext() {
  if (impl_->iotdbRpcDataSet_->hasCachedRecord()) {
    return true;
  }
  return impl_->iotdbRpcDataSet_->next();
}

shared_ptr<RowRecord> SessionDataSet::next() {
  if (!impl_->iotdbRpcDataSet_->hasCachedRecord() && !hasNext()) {
    return nullptr;
  }
  impl_->iotdbRpcDataSet_->setHasCachedRecord(false);
  return constructRowRecordFromValueArray();
}

int SessionDataSet::getFetchSize() {
  return impl_->iotdbRpcDataSet_->getFetchSize();
}

void SessionDataSet::setFetchSize(int fetchSize) {
  impl_->iotdbRpcDataSet_->setFetchSize(fetchSize);
}

const std::vector<std::string>& SessionDataSet::getColumnNames() const {
  return impl_->iotdbRpcDataSet_->getColumnNameList();
}

const std::vector<std::string>& SessionDataSet::getColumnTypeList() const {
  return impl_->iotdbRpcDataSet_->getColumnTypeList();
}

void SessionDataSet::closeOperationHandle(bool forceClose) {
  impl_->iotdbRpcDataSet_->close(forceClose);
}

SessionDataSet::DataIterator::DataIterator(std::shared_ptr<Impl> impl) : impl_(std::move(impl)) {}

bool SessionDataSet::DataIterator::next() {
  return impl_->iotdbRpcDataSet_->next();
}

bool SessionDataSet::DataIterator::isNull(const std::string& columnName) {
  return impl_->iotdbRpcDataSet_->isNullByColumnName(columnName);
}

bool SessionDataSet::DataIterator::isNullByIndex(int32_t columnIndex) {
  return impl_->iotdbRpcDataSet_->isNullByIndex(columnIndex);
}

Optional<bool> SessionDataSet::DataIterator::getBooleanByIndex(int32_t columnIndex) {
  return impl_->iotdbRpcDataSet_->getBooleanByIndex(columnIndex);
}

Optional<bool> SessionDataSet::DataIterator::getBoolean(const std::string& columnName) {
  return impl_->iotdbRpcDataSet_->getBoolean(columnName);
}

Optional<double> SessionDataSet::DataIterator::getDoubleByIndex(int32_t columnIndex) {
  return impl_->iotdbRpcDataSet_->getDoubleByIndex(columnIndex);
}

Optional<double> SessionDataSet::DataIterator::getDouble(const std::string& columnName) {
  return impl_->iotdbRpcDataSet_->getDouble(columnName);
}

Optional<float> SessionDataSet::DataIterator::getFloatByIndex(int32_t columnIndex) {
  return impl_->iotdbRpcDataSet_->getFloatByIndex(columnIndex);
}

Optional<float> SessionDataSet::DataIterator::getFloat(const std::string& columnName) {
  return impl_->iotdbRpcDataSet_->getFloat(columnName);
}

Optional<int32_t> SessionDataSet::DataIterator::getIntByIndex(int32_t columnIndex) {
  return impl_->iotdbRpcDataSet_->getIntByIndex(columnIndex);
}

Optional<int32_t> SessionDataSet::DataIterator::getInt(const std::string& columnName) {
  return impl_->iotdbRpcDataSet_->getInt(columnName);
}

Optional<int64_t> SessionDataSet::DataIterator::getLongByIndex(int32_t columnIndex) {
  return impl_->iotdbRpcDataSet_->getLongByIndex(columnIndex);
}

Optional<int64_t> SessionDataSet::DataIterator::getLong(const std::string& columnName) {
  return impl_->iotdbRpcDataSet_->getLong(columnName);
}

Optional<std::string> SessionDataSet::DataIterator::getStringByIndex(int32_t columnIndex) {
  return impl_->iotdbRpcDataSet_->getStringByIndex(columnIndex);
}

Optional<std::string> SessionDataSet::DataIterator::getString(const std::string& columnName) {
  return impl_->iotdbRpcDataSet_->getString(columnName);
}

Optional<int64_t> SessionDataSet::DataIterator::getTimestampByIndex(int32_t columnIndex) {
  return impl_->iotdbRpcDataSet_->getTimestampByIndex(columnIndex);
}

Optional<int64_t> SessionDataSet::DataIterator::getTimestamp(const std::string& columnName) {
  return impl_->iotdbRpcDataSet_->getTimestamp(columnName);
}

Optional<IoTDBDate> SessionDataSet::DataIterator::getDateByIndex(int32_t columnIndex) {
  return impl_->iotdbRpcDataSet_->getDateByIndex(columnIndex);
}

Optional<IoTDBDate> SessionDataSet::DataIterator::getDate(const std::string& columnName) {
  return impl_->iotdbRpcDataSet_->getDate(columnName);
}

int32_t SessionDataSet::DataIterator::findColumn(const std::string& columnName) {
  return impl_->iotdbRpcDataSet_->findColumn(columnName);
}

const std::vector<std::string>& SessionDataSet::DataIterator::getColumnNames() const {
  return impl_->iotdbRpcDataSet_->getColumnNameList();
}

const std::vector<std::string>& SessionDataSet::DataIterator::getColumnTypeList() const {
  return impl_->iotdbRpcDataSet_->getColumnTypeList();
}

SessionDataSet::DataIterator SessionDataSet::getIterator() {
  return DataIterator(std::shared_ptr<Impl>(impl_.get(), [](Impl*) {}));
}

shared_ptr<RowRecord> SessionDataSet::constructRowRecordFromValueArray() {
  std::vector<Field> outFields;
  for (int i = impl_->iotdbRpcDataSet_->getValueColumnStartIndex();
       i < impl_->iotdbRpcDataSet_->getColumnSize(); i++) {
    Field field;
    std::string columnName = impl_->iotdbRpcDataSet_->getColumnNameList().at(i);
    if (!impl_->iotdbRpcDataSet_->isNullByColumnName(columnName)) {
      TSDataType::TSDataType dataType = impl_->iotdbRpcDataSet_->getDataType(columnName);
      field.dataType = dataType;
      switch (dataType) {
      case TSDataType::BOOLEAN:
        field.boolV = impl_->iotdbRpcDataSet_->getBoolean(columnName);
        break;
      case TSDataType::INT32:
        field.intV = impl_->iotdbRpcDataSet_->getInt(columnName);
        break;
      case TSDataType::DATE:
        field.dateV = impl_->iotdbRpcDataSet_->getDate(columnName);
        break;
      case TSDataType::INT64:
      case TSDataType::TIMESTAMP:
        field.longV = impl_->iotdbRpcDataSet_->getLong(columnName);
        break;
      case TSDataType::FLOAT:
        field.floatV = impl_->iotdbRpcDataSet_->getFloat(columnName);
        break;
      case TSDataType::DOUBLE:
        field.doubleV = impl_->iotdbRpcDataSet_->getDouble(columnName);
        break;
      case TSDataType::TEXT:
      case TSDataType::BLOB:
      case TSDataType::STRING:
      case TSDataType::OBJECT:
        field.stringV = impl_->iotdbRpcDataSet_->getBinary(columnName)->getStringValue();
        break;
      default:
        throw UnSupportedDataTypeException("Data type is not supported.");
      }
    }
    outFields.emplace_back(field);
  }
  return std::make_shared<RowRecord>(impl_->iotdbRpcDataSet_->getCurrentRowTime(), outFields);
}
