/*
 * test_driver.cj - 数据库驱动测试
 */

package tybb2026::tycj_orm

import std.unittest.*

// ============================================================================
// 驱动管理器测试
// ============================================================================

@test
func testRegisterAndDeregisterDriver(): Unit {
    let driver = MockDriver()

    DriverManager.registerDriver(driver)

    let drivers = DriverManager.getDrivers()
    assert(drivers.size >= 1)

    DriverManager.deregisterDriver(driver)
}

@test
func testGetConnection(): Unit {
    let driver = MockDriver()
    DriverManager.registerDriver(driver)

    let config = DatabaseConfig()
    let connOpt = DriverManager.getConnection(config)

    assert(connOpt.isSome())

    DriverManager.clear()
}

@test
func testClearDrivers(): Unit {
    let driver = MockDriver()
    DriverManager.registerDriver(driver)

    DriverManager.clear()

    let drivers = DriverManager.getDrivers()
    assert(drivers.size == 0)
}

// ============================================================================
// Mock 驱动测试
// ============================================================================

@test
func testDriverInfo(): Unit {
    let driver = MockDriver()

    assert(driver.getName() == "MockDriver")
    assert(driver.getVersion() == "1.0.0")
    assert(driver.getSupportedDatabaseType() == DatabaseType.MySql)
}

@test
func testConnect(): Unit {
    let driver = MockDriver()
    let config = DatabaseConfig()

    let connOpt = driver.connect(config)

    assert(connOpt.isSome())
}

@test
func testAcceptsURL(): Unit {
    let driver = MockDriver()

    assert(driver.acceptsURL("mock:test"))
    assert(!driver.acceptsURL("jdbc:mysql://localhost"))
}

// ============================================================================
// 方言测试
// ============================================================================

@test
func testMySqlDialect(): Unit {
    let dialect = MySqlDialect()

    assert(dialect.getDatabaseType() == DatabaseType.MySql)
    assert(!dialect.supportsSequences())

    let paginationSql = dialect.getPaginationSql("SELECT * FROM users", 0, 10)
    assert(paginationSql.contains("LIMIT"))
    assert(paginationSql.contains("OFFSET"))

    let identitySql = dialect.getIdentitySelectSql()
    assert(identitySql.contains("LAST_INSERT_ID"))

    let quoted = dialect.quoteIdentifier("users")
    assert(quoted.contains("`"))
}

@test
func testPostgreSqlDialect(): Unit {
    let dialect = PostgreSqlDialect()

    assert(dialect.getDatabaseType() == DatabaseType.PostgreSQL)
    assert(dialect.supportsSequences())

    let paginationSql = dialect.getPaginationSql("SELECT * FROM users", 0, 10)
    assert(paginationSql.contains("LIMIT"))

    let sequenceSql = dialect.getSequenceNextValSql("seq_users")
    assert(sequenceSql.contains("nextval"))

    let quoted = dialect.quoteIdentifier("users")
    assert(quoted.contains("\""))
}

@test
func testSqliteDialect(): Unit {
    let dialect = SqliteDialect()

    assert(dialect.getDatabaseType() == DatabaseType.Sqlite)
    assert(!dialect.supportsSequences())

    let paginationSql = dialect.getPaginationSql("SELECT * FROM users", 0, 10)
    assert(paginationSql.contains("LIMIT"))

    let identitySql = dialect.getIdentitySelectSql()
    assert(identitySql.contains("last_insert_rowid"))
}

@test
func testDialectRegistry(): Unit {
    let mySqlDialect = DialectRegistry.getDialect(DatabaseType.MySql)
    assert(mySqlDialect.isSome())

    let pgDialect = DialectRegistry.getDialect(DatabaseType.PostgreSQL)
    assert(pgDialect.isSome())

    let sqliteDialect = DialectRegistry.getDialect(DatabaseType.Sqlite)
    assert(sqliteDialect.isSome())

    // Oracle 和 SQL Server 尚未实现
    let oracleDialect = DialectRegistry.getDialect(DatabaseType.Oracle)
    assert(oracleDialect.isNone())

    let sqlServerDialect = DialectRegistry.getDialect(DatabaseType.SqlServer)
    assert(sqlServerDialect.isNone())
}

// ============================================================================
// 连接工厂测试
// ============================================================================

@test
func testDefaultConnectionFactory(): Unit {
    let config = DatabaseConfig()
    let factory = DefaultConnectionFactory(config)

    let connOpt = factory.createConnection()
    // 由于没有注册驱动,应该返回 None
    assert(connOpt.isNone())
}

@test
func testMockConnectionFactory(): Unit {
    let factory = MockConnectionFactory()

    let connOpt = factory.createConnection()
    assert(connOpt.isSome())

    match (connOpt) {
        case Some(conn) => {
            assert(factory.validateConnection(conn))
            conn.close()
        }
        case None => ()
    }
}