// OracleDB.cpp
#include "OracleDB.h"
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>

OracleDB::OracleDB() : conn(nullptr), stmt(nullptr), isConnected(false) {}

OracleDB::~OracleDB() {
    disconnect();
}

bool OracleDB::connect(const char* user, const char* pwd, const char* host) {
    if (isConnected) return true;

   

    // 创建连接
    conn = OCI_ConnectionCreate(host, user, pwd, OCI_SESSION_DEFAULT);
    if (!conn) {
        printf("连接数据库失败: %s\n", OCI_GetLastError() ? OCI_ErrorGetString(OCI_GetLastError()) : "Unknown error");
        return false;
    }

    stmt = OCI_StatementCreate(conn);
    if (!stmt) {
        printf("创建语句对象失败\n");
        OCI_ConnectionFree(conn);
        conn = nullptr;
        return false;
    }

    isConnected = true;
    printf("数据库连接成功\n");
    return true;
}

void OracleDB::disconnect() {
    if (stmt) {
        OCI_StatementFree(stmt);
        stmt = nullptr;
    }
    if (conn) {
        OCI_ConnectionFree(conn);
        conn = nullptr;
    }
    isConnected = false;
}

int OracleDB::executeQuery(
    const char* sql,
    int* outputColumn,
    int* outputRow,
    char**** outputValue
) {
    // 初始化输出参数
    *outputColumn = 0;
    *outputRow = 0;
    *outputValue = nullptr;

    printf("初始化输出参数完成\n");

    if (!isConnected || !stmt) {
        printf("数据库未连接或语句对象无效\n");
        return -1;
    }

    printf("检查数据库连接成功\n");

    if (!OCI_ExecuteStmt(stmt, sql)) {
        printf("SQL执行失败: %s\n", OCI_ErrorGetString(OCI_GetLastError()));
        return -1;
    }

    printf("SQL语句执行成功\n");

    OCI_Resultset* rs = OCI_GetResultset(stmt);
    if (!rs) {
        printf("无法获取结果集\n");
        return -1;
    }

    printf("获取结果集成功\n");

    int colCount = (int)OCI_GetColumnCount(rs);
    printf("列数: %d\n", colCount);

    // 使用 vector 临时存储所有数据
    std::vector<std::vector<std::string>> tempData;

    int rowCount = 0;
    while (OCI_FetchNext(rs)) {
        std::vector<std::string> row;
        for (int j = 0; j < colCount; j++) {
            const char* val = OCI_GetString(rs, j + 1);
            if (val) {
                row.push_back(std::string(val));
            }
            else {
                row.push_back("NULL");
            }
        }
        tempData.push_back(row);
        rowCount++;
    }

    printf("遍历结果集完成，行数: %d\n", rowCount);

    // 分配 outputValue
    char*** result = (char***)calloc(rowCount, sizeof(char**));
    if (!result) {
        printf("内存分配失败\n");
        return -1;
    }
    printf("为结果分配内存完成\n");

    for (int i = 0; i < rowCount; i++) {
        result[i] = (char**)calloc(colCount, sizeof(char*));
        if (!result[i]) {
            // 清理已分配内存
            for (int j = 0; j < i; j++) {
                for (int k = 0; k < colCount; k++) {
                    free(result[j][k]);
                }
                free(result[j]);
            }
            free(result);
            printf("内存分配失败\n");
            return -1;
        }
        printf("为第 %d 行分配内存完成\n", i + 1);

        for (int j = 0; j < colCount; j++) {
            const std::string& val = tempData[i][j];
            result[i][j] = (char*)malloc(val.length() + 1);
            if (result[i][j]) {
                strcpy(result[i][j], val.c_str());
                printf("复制第 %d 行第 %d 列的数据: %s\n", i + 1, j + 1, result[i][j]);
            }
            else {
                result[i][j] = nullptr;
                printf("内存分配失败，设置第 %d 行第 %d 列为空指针\n", i + 1, j + 1);
            }
        }
    }

    // 设置输出参数
    *outputColumn = colCount;
    *outputRow = rowCount;
    *outputValue = result;

    printf("executeQuery 成功返回\n");
    return 0; // 成功
}