/*
 * utils.cj - 工具函数模块
 *
 * 提供 ORM 模块通用的工具函数。
 */

package tybb2026::tycj_orm

import std.collection.*

// ============================================================================
// 字符串工具函数
// ============================================================================

/**
 * 连接字符串列表
 * @param list 字符串列表
 * @param separator 分隔符
 * @return 连接后的字符串
 */
public func joinStrings(list: ArrayList<String>, separator: String): String {
    if (list.isEmpty()) {
        return ""
    }
    let sb = StringBuilder()
    for (i in 0..list.size) {
        if (i > 0) {
            sb.append(separator)
        }
        sb.append(list[i])
    }
    sb.toString()
}

/**
 * 将字符串转换为大写
 * @param s 输入字符串
 * @return 大写字符串
 */
public func toUpperCaseString(s: String): String {
    let sb = StringBuilder()
    for (i in 0..s.size) {
        let c = s[i]
        if (c >= 97u8 && c <= 122u8) { // a-z
            sb.append(String.fromUtf8([c - 32u8]))
        } else {
            sb.append(String.fromUtf8([c]))
        }
    }
    sb.toString()
}

/**
 * 将字符串转换为小写
 * @param s 输入字符串
 * @return 小写字符串
 */
public func toLowerCaseString(s: String): String {
    let sb = StringBuilder()
    for (i in 0..s.size) {
        let c = s[i]
        if (c >= 65u8 && c <= 90u8) { // A-Z
            sb.append(String.fromUtf8([c + 32u8]))
        } else {
            sb.append(String.fromUtf8([c]))
        }
    }
    sb.toString()
}

/**
 * 检查字符串是否以指定前缀开头(忽略大小写)
 * @param s 输入字符串
 * @param prefix 前缀
 * @return 是否以此前缀开头
 */
public func startsWithIgnoreCase(s: String, prefix: String): Bool {
    if (prefix.size > s.size) {
        return false
    }
    let sUpper = toUpperCaseString(s)
    let prefixUpper = toUpperCaseString(prefix)
    sUpper.startsWith(prefixUpper)
}

/**
 * 检查字符串是否包含子串(忽略大小写)
 * @param s 输入字符串
 * @param sub 子串
 * @return 是否包含
 */
public func containsIgnoreCase(s: String, sub: String): Bool {
    let sUpper = toUpperCaseString(s)
    let subUpper = toUpperCaseString(sub)
    sUpper.contains(subUpper)
}

// ============================================================================
// 集合工具函数
// ============================================================================

/**
 * 将列表分批处理
 * @param list 原始列表
 * @param batchSize 每批大小
 * @return 分批后的列表
 */
public func batchList<T>(list: ArrayList<T>, batchSize: Int64): ArrayList<ArrayList<T>> {
    let result = ArrayList<ArrayList<T>>()
    var currentBatch = ArrayList<T>()

    for (item in list) {
        currentBatch.add(item)
        if (currentBatch.size >= batchSize) {
            result.add(currentBatch)
            currentBatch = ArrayList<T>()
        }
    }

    if (!currentBatch.isEmpty()) {
        result.add(currentBatch)
    }

    result
}

// ============================================================================
// 验证工具函数
// ============================================================================

/**
 * 检查字符串是否为有效的标识符(表名、列名)
 * @param identifier 标识符
 * @return 是否有效
 */
public func isValidIdentifier(identifier: String): Bool {
    if (identifier.isEmpty()) {
        return false
    }

    // 检查首字符
    let first = identifier[0]
    if (!((first >= 65u8 && first <= 90u8) ||   // A-Z
          (first >= 97u8 && first <= 122u8) ||  // a-z
          (first == 95u8))) {                   // _
        return false
    }

    // 检查其余字符
    for (i in 1..identifier.size) {
        let c = identifier[i]
        if (!((c >= 65u8 && c <= 90u8) ||   // A-Z
              (c >= 97u8 && c <= 122u8) ||  // a-z
              (c >= 48u8 && c <= 57u8) ||   // 0-9
              (c == 95u8))) {               // _
            return false
        }
    }

    true
}

/**
 * 转义 SQL 标识符中的特殊字符
 * @param identifier 标识符
 * @return 转义后的标识符
 */
public func escapeIdentifier(identifier: String): String {
    // 移除可能导致 SQL 注入的字符
    var result = ""
    for (i in 0..identifier.size) {
        let c = identifier[i]
        // 只允许字母、数字、下划线
        if ((c >= 65u8 && c <= 90u8) ||   // A-Z
            (c >= 97u8 && c <= 122u8) ||  // a-z
            (c >= 48u8 && c <= 57u8) ||   // 0-9
            (c == 95u8)) {                // _
            result = result + String.fromUtf8([c])
        }
    }
    result
}