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

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

/* ============================================================
 *  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);
  }
#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;
}

/**
 * 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_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;
    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);
  }
}

/* ============================================================
 *  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);
  }
}

/* ============================================================
 *  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");
  tablet->cpp.rowSize = 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 "";
}

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