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

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

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

struct CSession_ {
  std::shared_ptr<Session> 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 {
    SessionBuilder builder;
    builder.host(host)
        ->rpcPort(rpcPort)
        ->username(username)
        ->password(password)
        ->enableAutoFetch(false);
    auto cpp = std::make_shared<Session>(&builder);
    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 {
    SessionBuilder builder;
    builder.host(host)
        ->rpcPort(rpcPort)
        ->username(username)
        ->password(password)
        ->zoneId(zoneId)
        ->fetchSize(fetchSize)
        ->enableAutoFetch(false);
    auto cpp = std::make_shared<Session>(&builder);
    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);
    SessionBuilder builder;
    builder.nodeUrls(urls)
        ->username(username)
        ->password(password)
        ->enableAutoFetch(false);
    auto cpp = std::make_shared<Session>(&builder);
    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);
  }
}

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

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);
  }
}

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

/* ============================================================
 *  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];
  if (f.longV.is_initialized())
    return f.longV.value();
  if (f.intV.is_initialized())
    return f.intV.value();
  if (f.doubleV.is_initialized())
    return static_cast<int64_t>(f.doubleV.value());
  return 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" */
