package de.avatic.lcc.repositories;

import de.avatic.lcc.config.DatabaseTestConfiguration;
import de.avatic.lcc.config.RepositoryTestConfig;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.annotation.Transactional;
import org.testcontainers.junit.jupiter.Testcontainers;

/**
 * Abstract base class for repository integration tests.
 * <p>
 * Provides TestContainers-based database setup for both MySQL and MSSQL.
 * Tests extending this class will run against the database specified by the active profile.
 * Flyway migrations from db/migration/{mysql|mssql}/ will be automatically applied.
 * <p>
 * Only loads Repository and JDBC beans, not the full application context (no Controllers, no API Services).
 * <p>
 * Usage:
 * <pre>
 * // Run against MySQL
 * mvn test -Dspring.profiles.active=test,mysql -Dtest=NodeRepositoryIntegrationTest
 *
 * // Run against MSSQL
 * mvn test -Dspring.profiles.active=test,mssql -Dtest=NodeRepositoryIntegrationTest
 * </pre>
 */
@SpringBootTest(
    classes = {RepositoryTestConfig.class},
    properties = {
        "spring.main.web-application-type=none",
        "spring.autoconfigure.exclude=" +
            "org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration," +
            "org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration," +
            "org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration," +
            "org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration," +
            "org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration"
    }
)
@Testcontainers
@Import(DatabaseTestConfiguration.class)
// NOTE: No @ActiveProfiles - profiles come from command line: -Dspring.profiles.active=test,mysql
@Transactional // Rollback after each test for isolation
public abstract class AbstractRepositoryIntegrationTest {

    @Autowired
    protected JdbcTemplate jdbcTemplate;

    @Autowired
    protected SqlDialectProvider dialectProvider;

    /**
     * Gets the active database profile (mysql or mssql).
     * Useful for profile-specific test assertions.
     */
    protected String getDatabaseProfile() {
        return System.getProperty("spring.profiles.active", "mysql");
    }

    /**
     * Checks if tests are running against MSSQL.
     */
    protected boolean isMssql() {
        return getDatabaseProfile().contains("mssql");
    }

    /**
     * Checks if tests are running against MySQL.
     */
    protected boolean isMysql() {
        return getDatabaseProfile().contains("mysql");
    }

    @BeforeEach
    void baseSetup() {
        // Common setup logic if needed
        // Flyway migrations are automatically applied by Spring Boot
    }

    /**
     * Executes a raw SQL query for test data setup.
     * Use with caution - prefer using repositories where possible.
     */
    protected void executeRawSql(String sql, Object... params) {
        jdbcTemplate.update(sql, params);
    }

    /**
     * Counts rows in a table.
     */
    protected int countRows(String tableName) {
        return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM " + tableName, Integer.class);
    }
}
