/**
 * 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 "SessionC.h"
#include "Date.h"
#include "Session.h"
#include "TableSession.h"
#include "TableSessionBuilder.h"
#include "SessionBuilder.h"
#include "SessionDataSet.h"

#include <cstring>
#include <map>
#include <memory>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <vector>

/* ============================================================
 *  Internal wrapper structs — the opaque handles point to these
 * ============================================================ */

struct CSession_ {
  std::shared_ptr<Session> cpp;
};

struct CTableSession_ {
  std::shared_ptr<TableSession> cpp;
};

struct CTablet_ {
  Tablet cpp;
};

struct CSessionDataSet_ {
  std::unique_ptr<SessionDataSet> cpp;
};

struct CRowRecord_ {
  std::shared_ptr<RowRecord> cpp;
};

/* ============================================================
 *  Thread-local error message buffer
 * ============================================================ */

static thread_local std::string g_lastError;

static void clearError() {
  g_lastError.clear();
}

static TsStatus setError(TsStatus code, const std::string& msg) {
  g_lastError = msg;
  return code;
}

static TsStatus setError(TsStatus code, const std::exception& e) {
  g_lastError = e.what();
  return code;
}

static TsStatus handleException(const std::exception& e) {
#if defined(_CPPRTTI) || defined(__GXX_RTTI)
  // Try to classify exception type (requires RTTI enabled).
  if (dynamic_cast<const IoTDBConnectionException*>(&e)) {
    return setError(TS_ERR_CONNECTION, e);
  }
  if (dynamic_cast<const ExecutionException*>(&e) ||
      dynamic_cast<const StatementExecutionException*>(&e) ||
      dynamic_cast<const BatchExecutionException*>(&e)) {
    return setError(TS_ERR_EXECUTION, e);
  }
  if (dynamic_cast<const std::out_of_range*>(&e) ||
      dynamic_cast<const std::invalid_argument*>(&e)) {
    return setError(TS_ERR_INVALID_PARAM, e);
  }
#endif
  return setError(TS_ERR_UNKNOWN, e);
}

extern "C" {

const char* ts_get_last_error(void) {
  return g_lastError.c_str();
}

} /* extern "C" */

/* ============================================================
 *  Helpers — convert C arrays to C++ vectors
 * ============================================================ */

static std::vector<std::string> toStringVec(const char* const* arr, int count) {
  std::vector<std::string> v;
  v.reserve(count);
  for (int i = 0; i < count; i++) {
    v.emplace_back(arr[i]);
  }
  return v;
}

static std::vector<TSDataType::TSDataType> toTypeVec(const TSDataType_C* arr, int count) {
  std::vector<TSDataType::TSDataType> v;
  v.reserve(count);
  for (int i = 0; i < count; i++) {
    v.push_back(static_cast<TSDataType::TSDataType>(arr[i]));
  }
  return v;
}

static std::vector<TSEncoding::TSEncoding> toEncodingVec(const TSEncoding_C* arr, int count) {
  std::vector<TSEncoding::TSEncoding> v;
  v.reserve(count);
  for (int i = 0; i < count; i++) {
    v.push_back(static_cast<TSEncoding::TSEncoding>(arr[i]));
  }
  return v;
}

static std::vector<CompressionType::CompressionType>
toCompressionVec(const TSCompressionType_C* arr, int count) {
  std::vector<CompressionType::CompressionType> v;
  v.reserve(count);
  for (int i = 0; i < count; i++) {
    v.push_back(static_cast<CompressionType::CompressionType>(arr[i]));
  }
  return v;
}

static std::map<std::string, std::string> toStringMap(int count, const char* const* keys,
                                                      const char* const* values) {
  std::map<std::string, std::string> m;
  for (int i = 0; i < count; i++) {
    m[keys[i]] = values[i];
  }
  return m;
}

static TsStatus setSslConfig(SslConfig& config, const char* trustCertFilePath,
                             const char* clientCertificateFilePath,
                             const char* clientPrivateKeyFilePath) {
  if (trustCertFilePath == nullptr) {
    return setError(TS_ERR_INVALID_PARAM, "trustCertFilePath is null");
  }
  if ((clientCertificateFilePath == nullptr) != (clientPrivateKeyFilePath == nullptr)) {
    return setError(TS_ERR_INVALID_PARAM,
                    "clientCertificateFilePath and clientPrivateKeyFilePath must both be null or "
                    "both be set");
  }
  config.useSsl = true;
  config.trustCertFilePath = trustCertFilePath;
  config.clientCertificateFilePath =
      clientCertificateFilePath == nullptr ? "" : clientCertificateFilePath;
  config.clientPrivateKeyFilePath =
      clientPrivateKeyFilePath == nullptr ? "" : clientPrivateKeyFilePath;
  return TS_OK;
}

/**
 * Convert C typed values (void* const* values, TSDataType_C* types, int count)
 * to C++ vector<char*> that Session expects.
 * The caller must free the returned char* pointers using freeCharPtrVec().
 */
static std::vector<char*> toCharPtrVec(const TSDataType_C* types, const void* const* values,
                                       int count) {
  std::vector<char*> result(count);
  for (int i = 0; i < count; i++) {
    switch (types[i]) {
    case TS_TYPE_BOOLEAN: {
      bool* p = new bool(*static_cast<const bool*>(values[i]));
      result[i] = reinterpret_cast<char*>(p);
      break;
    }
    case TS_TYPE_INT32: {
      int32_t* p = new int32_t(*static_cast<const int32_t*>(values[i]));
      result[i] = reinterpret_cast<char*>(p);
      break;
    }
    case TS_TYPE_INT64:
    case TS_TYPE_TIMESTAMP: {
      int64_t* p = new int64_t(*static_cast<const int64_t*>(values[i]));
      result[i] = reinterpret_cast<char*>(p);
      break;
    }
    case TS_TYPE_FLOAT: {
      float* p = new float(*static_cast<const float*>(values[i]));
      result[i] = reinterpret_cast<char*>(p);
      break;
    }
    case TS_TYPE_DOUBLE: {
      double* p = new double(*static_cast<const double*>(values[i]));
      result[i] = reinterpret_cast<char*>(p);
      break;
    }
    case TS_TYPE_DATE: {
      const TSDate_C* src = static_cast<const TSDate_C*>(values[i]);
      IoTDBDate* p = new IoTDBDate(src->year, src->month, src->day);
      result[i] = reinterpret_cast<char*>(p);
      break;
    }
    case TS_TYPE_TEXT:
    case TS_TYPE_STRING:
    case TS_TYPE_BLOB:
    default: {
      const char* src = static_cast<const char*>(values[i]);
      size_t len = strlen(src) + 1;
      char* p = new char[len];
      memcpy(p, src, len);
      result[i] = p;
      break;
    }
    }
  }
  return result;
}

static void freeCharPtrVec(std::vector<char*>& vec, const TSDataType_C* types, int count) {
  for (int i = 0; i < count; i++) {
    switch (types[i]) {
    case TS_TYPE_BOOLEAN:
      delete reinterpret_cast<bool*>(vec[i]);
      break;
    case TS_TYPE_INT32:
      delete reinterpret_cast<int32_t*>(vec[i]);
      break;
    case TS_TYPE_INT64:
    case TS_TYPE_TIMESTAMP:
      delete reinterpret_cast<int64_t*>(vec[i]);
      break;
    case TS_TYPE_FLOAT:
      delete reinterpret_cast<float*>(vec[i]);
      break;
    case TS_TYPE_DOUBLE:
      delete reinterpret_cast<double*>(vec[i]);
      break;
    case TS_TYPE_DATE:
      delete reinterpret_cast<IoTDBDate*>(vec[i]);
      break;
    default:
      delete[] vec[i];
      break;
    }
  }
}

/* ============================================================
 *  Session Lifecycle  —  Tree Model
 * ============================================================ */

extern "C" {

CSession* ts_session_new(const char* host, int rpcPort, const char* username,
                         const char* password) {
  clearError();
  try {
    auto cpp = std::make_shared<Session>(std::string(host), rpcPort, std::string(username),
                                         std::string(password));
    auto* cs = new CSession_();
    cs->cpp = std::move(cpp);
    return cs;
  } catch (const std::exception& e) {
    handleException(e);
    return nullptr;
  }
}

CSession* ts_session_new_with_zone(const char* host, int rpcPort, const char* username,
                                   const char* password, const char* zoneId, int fetchSize) {
  clearError();
  try {
    auto cpp = std::make_shared<Session>(std::string(host), rpcPort, std::string(username),
                                         std::string(password), std::string(zoneId), fetchSize);
    auto* cs = new CSession_();
    cs->cpp = std::move(cpp);
    return cs;
  } catch (const std::exception& e) {
    handleException(e);
    return nullptr;
  }
}

CSession* ts_session_new_multi_node(const char* const* nodeUrls, int urlCount, const char* username,
                                    const char* password) {
  clearError();
  try {
    auto urls = toStringVec(nodeUrls, urlCount);
    auto cpp = std::make_shared<Session>(urls, std::string(username), std::string(password));
    auto* cs = new CSession_();
    cs->cpp = std::move(cpp);
    return cs;
  } catch (const std::exception& e) {
    handleException(e);
    return nullptr;
  }
}

void ts_session_destroy(CSession* session) {
  delete session;
}

TsStatus ts_session_open(CSession* session) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->open();
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_open_with_compression(CSession* session, bool enableRPCCompression) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->open(enableRPCCompression);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_close(CSession* session) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->close();
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_set_ssl_config(CSession* session, const char* trustCertFilePath,
                                   const char* clientCertificateFilePath,
                                   const char* clientPrivateKeyFilePath) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    SslConfig config;
    TsStatus status = setSslConfig(config, trustCertFilePath, clientCertificateFilePath,
                                   clientPrivateKeyFilePath);
    if (status != TS_OK) {
      return status;
    }
    session->cpp->setSslConfig(config);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Session Lifecycle  —  Table Model
 * ============================================================ */

CTableSession* ts_table_session_new(const char* host, int rpcPort, const char* username,
                                    const char* password, const char* database) {
  clearError();
  try {
    std::unique_ptr<TableSessionBuilder> builder(new TableSessionBuilder());
    auto tableSession = builder->host(std::string(host))
                            ->rpcPort(rpcPort)
                            ->username(std::string(username))
                            ->password(std::string(password))
                            ->database(std::string(database ? database : ""))
                            ->build();
    CTableSession_ tmp{};
    tmp.cpp = std::move(tableSession);
    auto* cts = new CTableSession_();
    cts->cpp = std::move(tmp.cpp);
    return cts;
  } catch (const std::exception& e) {
    handleException(e);
    return nullptr;
  }
}

CTableSession* ts_table_session_new_multi_node(const char* const* nodeUrls, int urlCount,
                                               const char* username, const char* password,
                                               const char* database) {
  clearError();
  try {
    auto urls = toStringVec(nodeUrls, urlCount);
    std::unique_ptr<TableSessionBuilder> builder(new TableSessionBuilder());
    auto tableSession = builder->nodeUrls(urls)
                            ->username(std::string(username))
                            ->password(std::string(password))
                            ->database(std::string(database ? database : ""))
                            ->build();
    CTableSession_ tmp{};
    tmp.cpp = std::move(tableSession);
    auto* cts = new CTableSession_();
    cts->cpp = std::move(tmp.cpp);
    return cts;
  } catch (const std::exception& e) {
    handleException(e);
    return nullptr;
  }
}

void ts_table_session_destroy(CTableSession* session) {
  delete session;
}

TsStatus ts_table_session_open(CTableSession* session) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->open();
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_table_session_close(CTableSession* session) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->close();
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

CTableSession* ts_table_session_new_with_ssl(const char* host, int rpcPort, const char* username,
                                             const char* password, const char* database,
                                             const char* trustCertFilePath,
                                             const char* clientCertificateFilePath,
                                             const char* clientPrivateKeyFilePath) {
  clearError();
  try {
    SslConfig config;
    if (setSslConfig(config, trustCertFilePath, clientCertificateFilePath,
                     clientPrivateKeyFilePath) != TS_OK) {
      return nullptr;
    }
    TableSessionBuilder builder;
    builder.host(std::string(host))
        ->rpcPort(rpcPort)
        ->username(std::string(username))
        ->password(std::string(password))
        ->database(std::string(database ? database : ""));
    builder.sslConfig = config;
    auto tableSession = builder.build();
    auto* session = new CTableSession_();
    session->cpp = std::move(tableSession);
    return session;
  } catch (const std::exception& e) {
    handleException(e);
    return nullptr;
  }
}

/* ============================================================
 *  Timezone
 * ============================================================ */

TsStatus ts_session_set_timezone(CSession* session, const char* zoneId) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->setTimeZone(std::string(zoneId));
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_get_timezone(CSession* session, char* buf, int bufLen) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!buf || bufLen <= 0)
    return setError(TS_ERR_INVALID_PARAM, "invalid buffer");
  try {
    std::string tz = session->cpp->getTimeZone();
    if ((int)tz.size() >= bufLen) {
      return setError(TS_ERR_INVALID_PARAM, "buffer too small");
    }
    strncpy(buf, tz.c_str(), bufLen);
    buf[bufLen - 1] = '\0';
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Database Management  (Tree Model)
 * ============================================================ */

TsStatus ts_session_create_database(CSession* session, const char* database) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->createDatabase(std::string(database));
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_delete_database(CSession* session, const char* database) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->deleteDatabase(std::string(database));
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_delete_databases(CSession* session, const char* const* databases, int count) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto dbs = toStringVec(databases, count);
    session->cpp->deleteDatabases(dbs);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Timeseries Management  (Tree Model)
 * ============================================================ */

TsStatus ts_session_create_timeseries(CSession* session, const char* path, TSDataType_C dataType,
                                      TSEncoding_C encoding, TSCompressionType_C compressor) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->createTimeseries(std::string(path), static_cast<TSDataType::TSDataType>(dataType),
                                   static_cast<TSEncoding::TSEncoding>(encoding),
                                   static_cast<CompressionType::CompressionType>(compressor));
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_create_timeseries_ex(CSession* session, const char* path, TSDataType_C dataType,
                                         TSEncoding_C encoding, TSCompressionType_C compressor,
                                         int propsCount, const char* const* propKeys,
                                         const char* const* propValues, int tagsCount,
                                         const char* const* tagKeys, const char* const* tagValues,
                                         int attrsCount, const char* const* attrKeys,
                                         const char* const* attrValues,
                                         const char* measurementAlias) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    std::map<std::string, std::string> props = propsCount > 0
                                                   ? toStringMap(propsCount, propKeys, propValues)
                                                   : std::map<std::string, std::string>();
    std::map<std::string, std::string> tags = tagsCount > 0
                                                  ? toStringMap(tagsCount, tagKeys, tagValues)
                                                  : std::map<std::string, std::string>();
    std::map<std::string, std::string> attrs = attrsCount > 0
                                                   ? toStringMap(attrsCount, attrKeys, attrValues)
                                                   : std::map<std::string, std::string>();
    session->cpp->createTimeseries(std::string(path), static_cast<TSDataType::TSDataType>(dataType),
                                   static_cast<TSEncoding::TSEncoding>(encoding),
                                   static_cast<CompressionType::CompressionType>(compressor),
                                   &props, &tags, &attrs,
                                   std::string(measurementAlias ? measurementAlias : ""));
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_create_multi_timeseries(CSession* session, int count, const char* const* paths,
                                            const TSDataType_C* dataTypes,
                                            const TSEncoding_C* encodings,
                                            const TSCompressionType_C* compressors) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto pathsVec = toStringVec(paths, count);
    auto typesVec = toTypeVec(dataTypes, count);
    auto encVec = toEncodingVec(encodings, count);
    auto compVec = toCompressionVec(compressors, count);
    session->cpp->createMultiTimeseries(pathsVec, typesVec, encVec, compVec, nullptr, nullptr,
                                        nullptr, nullptr);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_create_aligned_timeseries(CSession* session, const char* deviceId, int count,
                                              const char* const* measurements,
                                              const TSDataType_C* dataTypes,
                                              const TSEncoding_C* encodings,
                                              const TSCompressionType_C* compressors) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto measurementsVec = toStringVec(measurements, count);
    auto typesVec = toTypeVec(dataTypes, count);
    auto encVec = toEncodingVec(encodings, count);
    auto compVec = toCompressionVec(compressors, count);
    session->cpp->createAlignedTimeseries(std::string(deviceId), measurementsVec, typesVec, encVec,
                                          compVec);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_check_timeseries_exists(CSession* session, const char* path, bool* exists) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!exists)
    return setError(TS_ERR_INVALID_PARAM, "exists pointer is null");
  try {
    *exists = session->cpp->checkTimeseriesExists(std::string(path));
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_delete_timeseries(CSession* session, const char* path) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->deleteTimeseries(std::string(path));
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_delete_timeseries_batch(CSession* session, const char* const* paths,
                                            int count) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto pathsVec = toStringVec(paths, count);
    session->cpp->deleteTimeseries(pathsVec);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Tablet Operations
 * ============================================================ */

CTablet* ts_tablet_new(const char* deviceId, int columnCount, const char* const* columnNames,
                       const TSDataType_C* dataTypes, int maxRowNumber) {
  try {
    std::vector<std::pair<std::string, TSDataType::TSDataType>> schemas;
    schemas.reserve(columnCount);
    for (int i = 0; i < columnCount; i++) {
      schemas.emplace_back(std::string(columnNames[i]),
                           static_cast<TSDataType::TSDataType>(dataTypes[i]));
    }
    Tablet tablet(std::string(deviceId), schemas, maxRowNumber);
    auto* ct = new CTablet_();
    ct->cpp = std::move(tablet);
    return ct;
  } catch (const std::exception& e) {
    handleException(e);
    return nullptr;
  }
}

CTablet* ts_tablet_new_with_category(const char* deviceId, int columnCount,
                                     const char* const* columnNames, const TSDataType_C* dataTypes,
                                     const TSColumnCategory_C* columnCategories, int maxRowNumber) {
  try {
    std::vector<std::pair<std::string, TSDataType::TSDataType>> schemas;
    std::vector<ColumnCategory> colTypes;
    schemas.reserve(columnCount);
    colTypes.reserve(columnCount);
    for (int i = 0; i < columnCount; i++) {
      schemas.emplace_back(std::string(columnNames[i]),
                           static_cast<TSDataType::TSDataType>(dataTypes[i]));
      colTypes.push_back(static_cast<ColumnCategory>(columnCategories[i]));
    }
    Tablet tablet(std::string(deviceId), schemas, colTypes, maxRowNumber);
    auto* ct = new CTablet_();
    ct->cpp = std::move(tablet);
    return ct;
  } catch (const std::exception& e) {
    handleException(e);
    return nullptr;
  }
}

void ts_tablet_destroy(CTablet* tablet) {
  delete tablet;
}

void ts_tablet_reset(CTablet* tablet) {
  if (tablet) {
    tablet->cpp.reset();
  }
}

int ts_tablet_get_row_count(CTablet* tablet) {
  if (!tablet)
    return 0;
  return static_cast<int>(tablet->cpp.rowSize);
}

TsStatus ts_tablet_set_row_count(CTablet* tablet, int rowCount) {
  clearError();
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  if (rowCount < 0 || static_cast<size_t>(rowCount) > tablet->cpp.maxRowNumber) {
    return setError(TS_ERR_INVALID_PARAM, "rowCount out of range [0, maxRowNumber]");
  }
  tablet->cpp.rowSize = static_cast<size_t>(rowCount);
  return TS_OK;
}

TsStatus ts_tablet_add_timestamp(CTablet* tablet, int rowIndex, int64_t timestamp) {
  clearError();
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  try {
    tablet->cpp.addTimestamp(static_cast<size_t>(rowIndex), timestamp);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_tablet_add_value_bool(CTablet* tablet, int colIndex, int rowIndex, bool value) {
  clearError();
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  try {
    tablet->cpp.addValue(static_cast<size_t>(colIndex), static_cast<size_t>(rowIndex), value);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_tablet_add_value_int32(CTablet* tablet, int colIndex, int rowIndex, int32_t value) {
  clearError();
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  try {
    tablet->cpp.addValue(static_cast<size_t>(colIndex), static_cast<size_t>(rowIndex), value);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_tablet_add_value_int64(CTablet* tablet, int colIndex, int rowIndex, int64_t value) {
  clearError();
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  try {
    tablet->cpp.addValue(static_cast<size_t>(colIndex), static_cast<size_t>(rowIndex), value);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_tablet_add_value_float(CTablet* tablet, int colIndex, int rowIndex, float value) {
  clearError();
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  try {
    tablet->cpp.addValue(static_cast<size_t>(colIndex), static_cast<size_t>(rowIndex), value);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_tablet_add_value_double(CTablet* tablet, int colIndex, int rowIndex, double value) {
  clearError();
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  try {
    tablet->cpp.addValue(static_cast<size_t>(colIndex), static_cast<size_t>(rowIndex), value);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_tablet_add_value_string(CTablet* tablet, int colIndex, int rowIndex,
                                    const char* value) {
  clearError();
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  try {
    std::string str(value);
    tablet->cpp.addValue(static_cast<size_t>(colIndex), static_cast<size_t>(rowIndex), str);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Data Insertion  —  Tree Model  (Record, string values)
 * ============================================================ */

TsStatus ts_session_insert_record_str(CSession* session, const char* deviceId, int64_t time,
                                      int count, const char* const* measurements,
                                      const char* const* values) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto measurementsVec = toStringVec(measurements, count);
    auto valuesVec = toStringVec(values, count);
    session->cpp->insertRecord(std::string(deviceId), time, measurementsVec, valuesVec);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_insert_record(CSession* session, const char* deviceId, int64_t time, int count,
                                  const char* const* measurements, const TSDataType_C* types,
                                  const void* const* values) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto measurementsVec = toStringVec(measurements, count);
    auto typesVec = toTypeVec(types, count);
    auto charVec = toCharPtrVec(types, values, count);
    session->cpp->insertRecord(std::string(deviceId), time, measurementsVec, typesVec, charVec);
    freeCharPtrVec(charVec, types, count);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_insert_aligned_record_str(CSession* session, const char* deviceId, int64_t time,
                                              int count, const char* const* measurements,
                                              const char* const* values) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto measurementsVec = toStringVec(measurements, count);
    auto valuesVec = toStringVec(values, count);
    session->cpp->insertAlignedRecord(std::string(deviceId), time, measurementsVec, valuesVec);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_insert_aligned_record(CSession* session, const char* deviceId, int64_t time,
                                          int count, const char* const* measurements,
                                          const TSDataType_C* types, const void* const* values) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto measurementsVec = toStringVec(measurements, count);
    auto typesVec = toTypeVec(types, count);
    auto charVec = toCharPtrVec(types, values, count);
    session->cpp->insertAlignedRecord(std::string(deviceId), time, measurementsVec, typesVec,
                                      charVec);
    freeCharPtrVec(charVec, types, count);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Data Insertion  —  Batch, multiple devices (string values)
 * ============================================================ */

TsStatus ts_session_insert_records_str(CSession* session, int deviceCount,
                                       const char* const* deviceIds, const int64_t* times,
                                       const int* measurementCounts,
                                       const char* const* const* measurementsList,
                                       const char* const* const* valuesList) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto devVec = toStringVec(deviceIds, deviceCount);
    std::vector<int64_t> timesVec(times, times + deviceCount);
    std::vector<std::vector<std::string>> mList, vList;
    mList.reserve(deviceCount);
    vList.reserve(deviceCount);
    for (int i = 0; i < deviceCount; i++) {
      mList.push_back(toStringVec(measurementsList[i], measurementCounts[i]));
      vList.push_back(toStringVec(valuesList[i], measurementCounts[i]));
    }
    session->cpp->insertRecords(devVec, timesVec, mList, vList);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_insert_aligned_records_str(CSession* session, int deviceCount,
                                               const char* const* deviceIds, const int64_t* times,
                                               const int* measurementCounts,
                                               const char* const* const* measurementsList,
                                               const char* const* const* valuesList) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto devVec = toStringVec(deviceIds, deviceCount);
    std::vector<int64_t> timesVec(times, times + deviceCount);
    std::vector<std::vector<std::string>> mList, vList;
    mList.reserve(deviceCount);
    vList.reserve(deviceCount);
    for (int i = 0; i < deviceCount; i++) {
      mList.push_back(toStringVec(measurementsList[i], measurementCounts[i]));
      vList.push_back(toStringVec(valuesList[i], measurementCounts[i]));
    }
    session->cpp->insertAlignedRecords(devVec, timesVec, mList, vList);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Data Insertion  —  Batch, multiple devices (typed values)
 * ============================================================ */

TsStatus ts_session_insert_records(CSession* session, int deviceCount, const char* const* deviceIds,
                                   const int64_t* times, const int* measurementCounts,
                                   const char* const* const* measurementsList,
                                   const TSDataType_C* const* typesList,
                                   const void* const* const* valuesList) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto devVec = toStringVec(deviceIds, deviceCount);
    std::vector<int64_t> timesVec(times, times + deviceCount);
    std::vector<std::vector<std::string>> mList;
    std::vector<std::vector<TSDataType::TSDataType>> tList;
    std::vector<std::vector<char*>> vList;
    mList.reserve(deviceCount);
    tList.reserve(deviceCount);
    vList.reserve(deviceCount);
    for (int i = 0; i < deviceCount; i++) {
      mList.push_back(toStringVec(measurementsList[i], measurementCounts[i]));
      tList.push_back(toTypeVec(typesList[i], measurementCounts[i]));
      vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i]));
    }
    session->cpp->insertRecords(devVec, timesVec, mList, tList, vList);
    for (int i = 0; i < deviceCount; i++) {
      freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]);
    }
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_insert_aligned_records(CSession* session, int deviceCount,
                                           const char* const* deviceIds, const int64_t* times,
                                           const int* measurementCounts,
                                           const char* const* const* measurementsList,
                                           const TSDataType_C* const* typesList,
                                           const void* const* const* valuesList) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto devVec = toStringVec(deviceIds, deviceCount);
    std::vector<int64_t> timesVec(times, times + deviceCount);
    std::vector<std::vector<std::string>> mList;
    std::vector<std::vector<TSDataType::TSDataType>> tList;
    std::vector<std::vector<char*>> vList;
    mList.reserve(deviceCount);
    tList.reserve(deviceCount);
    vList.reserve(deviceCount);
    for (int i = 0; i < deviceCount; i++) {
      mList.push_back(toStringVec(measurementsList[i], measurementCounts[i]));
      tList.push_back(toTypeVec(typesList[i], measurementCounts[i]));
      vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i]));
    }
    session->cpp->insertAlignedRecords(devVec, timesVec, mList, tList, vList);
    for (int i = 0; i < deviceCount; i++) {
      freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]);
    }
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Data Insertion  —  Batch, single device (typed values)
 * ============================================================ */

TsStatus ts_session_insert_records_of_one_device(
    CSession* session, const char* deviceId, int rowCount, const int64_t* times,
    const int* measurementCounts, const char* const* const* measurementsList,
    const TSDataType_C* const* typesList, const void* const* const* valuesList, bool sorted) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    std::vector<int64_t> timesVec(times, times + rowCount);
    std::vector<std::vector<std::string>> mList;
    std::vector<std::vector<TSDataType::TSDataType>> tList;
    std::vector<std::vector<char*>> vList;
    mList.reserve(rowCount);
    tList.reserve(rowCount);
    vList.reserve(rowCount);
    for (int i = 0; i < rowCount; i++) {
      mList.push_back(toStringVec(measurementsList[i], measurementCounts[i]));
      tList.push_back(toTypeVec(typesList[i], measurementCounts[i]));
      vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i]));
    }
    session->cpp->insertRecordsOfOneDevice(std::string(deviceId), timesVec, mList, tList, vList,
                                           sorted);
    for (int i = 0; i < rowCount; i++) {
      freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]);
    }
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_insert_aligned_records_of_one_device(
    CSession* session, const char* deviceId, int rowCount, const int64_t* times,
    const int* measurementCounts, const char* const* const* measurementsList,
    const TSDataType_C* const* typesList, const void* const* const* valuesList, bool sorted) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    std::vector<int64_t> timesVec(times, times + rowCount);
    std::vector<std::vector<std::string>> mList;
    std::vector<std::vector<TSDataType::TSDataType>> tList;
    std::vector<std::vector<char*>> vList;
    mList.reserve(rowCount);
    tList.reserve(rowCount);
    vList.reserve(rowCount);
    for (int i = 0; i < rowCount; i++) {
      mList.push_back(toStringVec(measurementsList[i], measurementCounts[i]));
      tList.push_back(toTypeVec(typesList[i], measurementCounts[i]));
      vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i]));
    }
    session->cpp->insertAlignedRecordsOfOneDevice(std::string(deviceId), timesVec, mList, tList,
                                                  vList, sorted);
    for (int i = 0; i < rowCount; i++) {
      freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]);
    }
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Data Insertion  —  Tree Model  (Tablet)
 * ============================================================ */

TsStatus ts_session_insert_tablet(CSession* session, CTablet* tablet, bool sorted) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  try {
    session->cpp->insertTablet(tablet->cpp, sorted);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_insert_aligned_tablet(CSession* session, CTablet* tablet, bool sorted) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  try {
    session->cpp->insertAlignedTablet(tablet->cpp, sorted);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_insert_tablets(CSession* session, int tabletCount, const char* const* deviceIds,
                                   CTablet** tablets, bool sorted) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    std::unordered_map<std::string, Tablet*> tabletMap;
    for (int i = 0; i < tabletCount; i++) {
      tabletMap[std::string(deviceIds[i])] = &(tablets[i]->cpp);
    }
    session->cpp->insertTablets(tabletMap, sorted);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_insert_aligned_tablets(CSession* session, int tabletCount,
                                           const char* const* deviceIds, CTablet** tablets,
                                           bool sorted) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    std::unordered_map<std::string, Tablet*> tabletMap;
    for (int i = 0; i < tabletCount; i++) {
      tabletMap[std::string(deviceIds[i])] = &(tablets[i]->cpp);
    }
    session->cpp->insertAlignedTablets(tabletMap, sorted);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Data Insertion  —  Table Model  (Tablet)
 * ============================================================ */

TsStatus ts_table_session_insert(CTableSession* session, CTablet* tablet) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!tablet)
    return setError(TS_ERR_NULL_PTR, "tablet is null");
  try {
    session->cpp->insert(tablet->cpp);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  Query  —  Tree Model
 * ============================================================ */

TsStatus ts_session_execute_query(CSession* session, const char* sql, CSessionDataSet** dataSet) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!dataSet)
    return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null");
  try {
    auto ds = session->cpp->executeQueryStatement(std::string(sql));
    CSessionDataSet_ tmp{};
    tmp.cpp = std::move(ds);
    auto* cds = new CSessionDataSet_();
    cds->cpp = std::move(tmp.cpp);
    *dataSet = cds;
    return TS_OK;
  } catch (const std::exception& e) {
    *dataSet = nullptr;
    return handleException(e);
  }
}

TsStatus ts_session_execute_query_with_timeout(CSession* session, const char* sql,
                                               int64_t timeoutInMs, CSessionDataSet** dataSet) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!dataSet)
    return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null");
  try {
    auto ds = session->cpp->executeQueryStatement(std::string(sql), timeoutInMs);
    CSessionDataSet_ tmp{};
    tmp.cpp = std::move(ds);
    auto* cds = new CSessionDataSet_();
    cds->cpp = std::move(tmp.cpp);
    *dataSet = cds;
    return TS_OK;
  } catch (const std::exception& e) {
    *dataSet = nullptr;
    return handleException(e);
  }
}

TsStatus ts_session_execute_non_query(CSession* session, const char* sql) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->executeNonQueryStatement(std::string(sql));
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_execute_raw_data_query(CSession* session, int pathCount,
                                           const char* const* paths, int64_t startTime,
                                           int64_t endTime, CSessionDataSet** dataSet) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!dataSet)
    return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null");
  try {
    auto pathsVec = toStringVec(paths, pathCount);
    auto ds = session->cpp->executeRawDataQuery(pathsVec, startTime, endTime);
    CSessionDataSet_ tmp{};
    tmp.cpp = std::move(ds);
    auto* cds = new CSessionDataSet_();
    cds->cpp = std::move(tmp.cpp);
    *dataSet = cds;
    return TS_OK;
  } catch (const std::exception& e) {
    *dataSet = nullptr;
    return handleException(e);
  }
}

TsStatus ts_session_execute_last_data_query(CSession* session, int pathCount,
                                            const char* const* paths, CSessionDataSet** dataSet) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!dataSet)
    return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null");
  try {
    auto pathsVec = toStringVec(paths, pathCount);
    auto ds = session->cpp->executeLastDataQuery(pathsVec);
    CSessionDataSet_ tmp{};
    tmp.cpp = std::move(ds);
    auto* cds = new CSessionDataSet_();
    cds->cpp = std::move(tmp.cpp);
    *dataSet = cds;
    return TS_OK;
  } catch (const std::exception& e) {
    *dataSet = nullptr;
    return handleException(e);
  }
}

TsStatus ts_session_execute_last_data_query_with_time(CSession* session, int pathCount,
                                                      const char* const* paths, int64_t lastTime,
                                                      CSessionDataSet** dataSet) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!dataSet)
    return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null");
  try {
    auto pathsVec = toStringVec(paths, pathCount);
    auto ds = session->cpp->executeLastDataQuery(pathsVec, lastTime);
    CSessionDataSet_ tmp{};
    tmp.cpp = std::move(ds);
    auto* cds = new CSessionDataSet_();
    cds->cpp = std::move(tmp.cpp);
    *dataSet = cds;
    return TS_OK;
  } catch (const std::exception& e) {
    *dataSet = nullptr;
    return handleException(e);
  }
}

/* ============================================================
 *  Query  —  Table Model
 * ============================================================ */

TsStatus ts_table_session_execute_query(CTableSession* session, const char* sql,
                                        CSessionDataSet** dataSet) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!dataSet)
    return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null");
  try {
    auto ds = session->cpp->executeQueryStatement(std::string(sql));
    CSessionDataSet_ tmp{};
    tmp.cpp = std::move(ds);
    auto* cds = new CSessionDataSet_();
    cds->cpp = std::move(tmp.cpp);
    *dataSet = cds;
    return TS_OK;
  } catch (const std::exception& e) {
    *dataSet = nullptr;
    return handleException(e);
  }
}

TsStatus ts_table_session_execute_query_with_timeout(CTableSession* session, const char* sql,
                                                     int64_t timeoutInMs,
                                                     CSessionDataSet** dataSet) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  if (!dataSet)
    return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null");
  try {
    auto ds = session->cpp->executeQueryStatement(std::string(sql), timeoutInMs);
    CSessionDataSet_ tmp{};
    tmp.cpp = std::move(ds);
    auto* cds = new CSessionDataSet_();
    cds->cpp = std::move(tmp.cpp);
    *dataSet = cds;
    return TS_OK;
  } catch (const std::exception& e) {
    *dataSet = nullptr;
    return handleException(e);
  }
}

TsStatus ts_table_session_execute_non_query(CTableSession* session, const char* sql) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->executeNonQueryStatement(std::string(sql));
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

/* ============================================================
 *  SessionDataSet & RowRecord  —  Result Iteration
 * ============================================================ */

void ts_dataset_destroy(CSessionDataSet* dataSet) {
  if (dataSet) {
    if (dataSet->cpp) {
      dataSet->cpp->closeOperationHandle();
    }
    delete dataSet;
  }
}

bool ts_dataset_has_next(CSessionDataSet* dataSet) {
  clearError();
  if (!dataSet) {
    (void)setError(TS_ERR_NULL_PTR, "dataSet is null");
    return false;
  }
  if (!dataSet->cpp) {
    (void)setError(TS_ERR_NULL_PTR, "dataSet is not initialized");
    return false;
  }
  try {
    return dataSet->cpp->hasNext();
  } catch (const std::exception& e) {
    (void)handleException(e);
    return false;
  } catch (...) {
    (void)setError(TS_ERR_UNKNOWN, "non-standard exception");
    return false;
  }
}

CRowRecord* ts_dataset_next(CSessionDataSet* dataSet) {
  clearError();
  if (!dataSet) {
    (void)setError(TS_ERR_NULL_PTR, "dataSet is null");
    return nullptr;
  }
  if (!dataSet->cpp) {
    (void)setError(TS_ERR_NULL_PTR, "dataSet is not initialized");
    return nullptr;
  }
  try {
    auto row = dataSet->cpp->next();
    if (!row)
      return nullptr;
    CRowRecord_ tmp{};
    tmp.cpp = std::move(row);
    auto* crr = new CRowRecord_();
    crr->cpp = std::move(tmp.cpp);
    return crr;
  } catch (const std::exception& e) {
    (void)handleException(e);
    return nullptr;
  } catch (...) {
    (void)setError(TS_ERR_UNKNOWN, "non-standard exception");
    return nullptr;
  }
}

int ts_dataset_get_column_count(CSessionDataSet* dataSet) {
  if (!dataSet || !dataSet->cpp)
    return 0;
  return static_cast<int>(dataSet->cpp->getColumnNames().size());
}

static thread_local std::string g_colNameBuf;

const char* ts_dataset_get_column_name(CSessionDataSet* dataSet, int index) {
  if (!dataSet || !dataSet->cpp)
    return "";
  const auto& names = dataSet->cpp->getColumnNames();
  if (index < 0 || index >= (int)names.size())
    return "";
  g_colNameBuf = names[index];
  return g_colNameBuf.c_str();
}

static thread_local std::string g_colTypeBuf;

const char* ts_dataset_get_column_type(CSessionDataSet* dataSet, int index) {
  if (!dataSet || !dataSet->cpp)
    return "";
  const auto& types = dataSet->cpp->getColumnTypeList();
  if (index < 0 || index >= (int)types.size())
    return "";
  g_colTypeBuf = types[index];
  return g_colTypeBuf.c_str();
}

void ts_dataset_set_fetch_size(CSessionDataSet* dataSet, int fetchSize) {
  if (dataSet && dataSet->cpp) {
    dataSet->cpp->setFetchSize(fetchSize);
  }
}

void ts_row_record_destroy(CRowRecord* record) {
  delete record;
}

int64_t ts_row_record_get_timestamp(CRowRecord* record) {
  if (!record || !record->cpp)
    return -1;
  return record->cpp->timestamp;
}

int ts_row_record_get_field_count(CRowRecord* record) {
  if (!record || !record->cpp)
    return 0;
  return static_cast<int>(record->cpp->fields.size());
}

bool ts_row_record_is_null(CRowRecord* record, int index) {
  if (!record || !record->cpp)
    return true;
  if (index < 0 || index >= (int)record->cpp->fields.size())
    return true;
  return record->cpp->fields[index].isNull();
}

bool ts_row_record_get_bool(CRowRecord* record, int index) {
  if (!record || !record->cpp)
    return false;
  if (index < 0 || index >= (int)record->cpp->fields.size())
    return false;
  const Field& f = record->cpp->fields[index];
  return f.boolV.is_initialized() ? f.boolV.value() : false;
}

int32_t ts_row_record_get_int32(CRowRecord* record, int index) {
  if (!record || !record->cpp)
    return 0;
  if (index < 0 || index >= (int)record->cpp->fields.size())
    return 0;
  const Field& f = record->cpp->fields[index];
  return f.intV.is_initialized() ? f.intV.value() : 0;
}

int64_t ts_row_record_get_int64(CRowRecord* record, int index) {
  if (!record || !record->cpp)
    return 0;
  if (index < 0 || index >= (int)record->cpp->fields.size())
    return 0;
  const Field& f = record->cpp->fields[index];
  return f.longV.is_initialized() ? f.longV.value() : 0;
}

float ts_row_record_get_float(CRowRecord* record, int index) {
  if (!record || !record->cpp)
    return 0.0f;
  if (index < 0 || index >= (int)record->cpp->fields.size())
    return 0.0f;
  const Field& f = record->cpp->fields[index];
  return f.floatV.is_initialized() ? f.floatV.value() : 0.0f;
}

double ts_row_record_get_double(CRowRecord* record, int index) {
  if (!record || !record->cpp)
    return 0.0;
  if (index < 0 || index >= (int)record->cpp->fields.size())
    return 0.0;
  const Field& f = record->cpp->fields[index];
  return f.doubleV.is_initialized() ? f.doubleV.value() : 0.0;
}

static thread_local std::string g_stringBuf;

const char* ts_row_record_get_string(CRowRecord* record, int index) {
  if (!record || !record->cpp)
    return "";
  if (index < 0 || index >= (int)record->cpp->fields.size())
    return "";
  const Field& f = record->cpp->fields[index];
  if (f.stringV.is_initialized()) {
    g_stringBuf = f.stringV.value();
    return g_stringBuf.c_str();
  }
  return "";
}

int32_t ts_row_record_get_date_int32(CRowRecord* record, int index) {
  if (!record || !record->cpp)
    return 0;
  if (index < 0 || index >= (int)record->cpp->fields.size())
    return 0;
  const Field& f = record->cpp->fields[index];
  if (f.dataType != TSDataType::DATE || !f.dateV.is_initialized() ||
      f.dateV.value().is_not_a_date()) {
    return 0;
  }
  return parseDateExpressionToInt(f.dateV.value());
}

size_t ts_row_record_get_string_byte_length(CRowRecord* record, int index) {
  if (!record || !record->cpp)
    return 0;
  if (index < 0 || index >= (int)record->cpp->fields.size())
    return 0;
  const Field& f = record->cpp->fields[index];
  if (f.stringV.is_initialized()) {
    return f.stringV.value().size();
  }
  return 0;
}

TSDataType_C ts_row_record_get_data_type(CRowRecord* record, int index) {
  if (!record || !record->cpp)
    return TS_TYPE_INVALID;
  if (index < 0 || index >= (int)record->cpp->fields.size())
    return TS_TYPE_INVALID;
  return static_cast<TSDataType_C>(record->cpp->fields[index].dataType);
}

/* ============================================================
 *  Data Deletion  (Tree Model)
 * ============================================================ */

TsStatus ts_session_delete_data(CSession* session, const char* path, int64_t endTime) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    session->cpp->deleteData(std::string(path), endTime);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_delete_data_batch(CSession* session, int pathCount, const char* const* paths,
                                      int64_t endTime) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto pathsVec = toStringVec(paths, pathCount);
    session->cpp->deleteData(pathsVec, endTime);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

TsStatus ts_session_delete_data_range(CSession* session, int pathCount, const char* const* paths,
                                      int64_t startTime, int64_t endTime) {
  clearError();
  if (!session)
    return setError(TS_ERR_NULL_PTR, "session is null");
  try {
    auto pathsVec = toStringVec(paths, pathCount);
    session->cpp->deleteData(pathsVec, startTime, endTime);
    return TS_OK;
  } catch (const std::exception& e) {
    return handleException(e);
  }
}

} /* extern "C" */
