'use strict';

// ============================================
// CursorPro SQLite Utils - 反混淆版本
// ============================================

const { exec } = require('child_process');
const { promisify } = require('util');
const fs = require('fs');

const execAsync = promisify(exec);

/**
 * 转义 SQL 字符串中的单引号
 */
function escapeSqlString(value) {
    if (value === null || value === undefined) {
        return '';
    }
    return String(value).replace(/'/g, "''");
}

/**
 * 执行 SQLite 命令
 * @param {string} dbPath - 数据库文件路径
 * @param {string} sql - SQL 语句
 * @returns {Promise<string>} - 执行结果
 */
async function execSqlite(dbPath, sql) {
    const isWindows = process.platform === 'win32';

    try {
        if (isWindows) {
            // Windows: 直接使用 sqlite3 命令
            const escapedSql = sql.replace(/"/g, '\\"');
            const command = `sqlite3 "${dbPath}" "${escapedSql}"`;

            const { stdout, stderr } = await execAsync(command, {
                encoding: 'utf-8',
                maxBuffer: 10 * 1024 * 1024 // 10MB
            });

            if (stderr && !stderr.includes('-- Loading')) {
                console.warn('[SQLite] stderr:', stderr);
            }

            return stdout.trim();
        } else {
            // macOS/Linux: 使用临时文件避免转义问题
            const os = require('os');
            const pathModule = require('path');
            const tempFile = pathModule.join(
                os.tmpdir(),
                'cursor_sql_' + Date.now() + '.sql'
            );

            // 写入 SQL 到临时文件
            fs.writeFileSync(tempFile, sql, 'utf-8');

            try {
                const command = `sqlite3 "${dbPath}" < "${tempFile}"`;

                const { stdout, stderr } = await execAsync(command, {
                    encoding: 'utf-8',
                    maxBuffer: 10 * 1024 * 1024,
                    shell: '/bin/bash'
                });

                if (stderr && !stderr.includes('-- Loading')) {
                    console.warn('[SQLite] stderr:', stderr);
                }

                return stdout.trim();
            } finally {
                // 清理临时文件
                try {
                    fs.unlinkSync(tempFile);
                } catch (e) {}
            }
        }
    } catch (error) {
        // 检查是否是 sqlite3 不存在的错误
        if (
            error.message === 'ENOENT' ||
            error.message?.includes('sqlite3') ||
            error.message?.includes('not found')
        ) {
            throw new Error('sqlite3 命令不存在，请先安装 SQLite3');
        }
        throw error;
    }
}

/**
 * 从 SQLite 数据库读取单个值
 * @param {string} dbPath - 数据库路径
 * @param {string} key - 键名
 * @returns {Promise<string|null>} - 值或 null
 */
async function sqliteGet(dbPath, key) {
    if (!fs.existsSync(dbPath)) {
        console.warn('[SQLite] 数据库文件不存在:', dbPath);
        return null;
    }

    try {
        const sql = `SELECT value FROM ItemTable WHERE key = '${escapeSqlString(key)}';`;
        const result = await execSqlite(dbPath, sql);
        return result || null;
    } catch (error) {
        console.error('[SQLite] 读取失败:', error);
        return null;
    }
}
exports.sqliteGet = sqliteGet;

/**
 * 向 SQLite 数据库写入单个值
 * @param {string} dbPath - 数据库路径
 * @param {string} key - 键名
 * @param {string} value - 值
 * @returns {Promise<boolean>} - 是否成功
 */
async function sqliteSet(dbPath, key, value) {
    if (!fs.existsSync(dbPath)) {
        console.warn('[SQLite] 数据库文件不存在:', dbPath);
        return false;
    }

    try {
        // 使用 REPLACE INTO 实现 upsert
        const sql = `REPLACE INTO ItemTable (key, value) VALUES ('${escapeSqlString(key)}', '${escapeSqlString(value)}');`;
        await execSqlite(dbPath, sql);
        return true;
    } catch (error) {
        console.error('[SQLite] 写入失败:', error);
        return false;
    }
}
exports.sqliteSet = sqliteSet;

/**
 * 批量写入 SQLite 数据库
 * @param {string} dbPath - 数据库路径
 * @param {Array<[string, string]>} kvPairs - 键值对数组
 * @returns {Promise<boolean>} - 是否成功
 */
async function sqliteSetBatch(dbPath, kvPairs) {
    if (!fs.existsSync(dbPath)) {
        console.warn('[SQLite] 数据库文件不存在:', dbPath);
        return false;
    }

    if (kvPairs.length === 0) {
        return true;
    }

    try {
        // 构建批量 SQL 语句
        const statements = kvPairs.map(([key, value]) =>
            `REPLACE INTO ItemTable (key, value) VALUES ('${escapeSqlString(key)}', '${escapeSqlString(value)}');`
        );

        const sql = 'BEGIN TRANSACTION; ' + statements.join(' ') + ' COMMIT;';

        await execSqlite(dbPath, sql);
        return true;
    } catch (error) {
        console.error('[SQLite] 批量写入失败:', error);
        return false;
    }
}
exports.sqliteSetBatch = sqliteSetBatch;

/**
 * 批量读取 SQLite 数据库
 * @param {string} dbPath - 数据库路径
 * @param {string[]} keys - 键名数组
 * @returns {Promise<Map<string, string|null>>} - 键值 Map
 */
async function sqliteGetBatch(dbPath, keys) {
    const resultMap = new Map();

    if (!fs.existsSync(dbPath)) {
        console.warn('[SQLite] 数据库文件不存在:', dbPath);
        keys.forEach(key => resultMap.set(key, null));
        return resultMap;
    }

    try {
        // 逐个读取 (SQLite CLI 批量读取输出解析较复杂)
        for (const key of keys) {
            const value = await sqliteGet(dbPath, key);
            resultMap.set(key, value);
        }
        return resultMap;
    } catch (error) {
        console.error('[SQLite] 批量读取失败:', error);
        keys.forEach(key => resultMap.set(key, null));
        return resultMap;
    }
}
exports.sqliteGetBatch = sqliteGetBatch;
