package tech.easyflow.skill.mapper;

import org.junit.Test;

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 * V31 Skill 内容写入意图迁移契约测试。
 */
public class SkillContentWriteIntentMigrationContractTest {

    /**
     * 验证 storage_locator 通过 information_schema 守卫幂等添加。
     *
     * @throws Exception 迁移文件不可读
     */
    @Test
    public void storageLocatorAlterIsIdempotent() throws Exception {
        String sql = migrationSql();

        assertTrue(sql.contains("FROM information_schema.columns"));
        assertTrue(sql.contains("table_name = 'tb_skill_content'"));
        assertTrue(sql.contains("column_name = 'storage_locator'"));
        assertTrue(sql.contains("ADD COLUMN `storage_locator` VARCHAR(2048) NULL"));
        assertTrue(sql.contains("PREPARE skill_content_storage_locator_stmt"));
        assertFalse(sql.contains("ADD COLUMN IF NOT EXISTS"));
    }

    /**
     * 验证写入意图表与正式内容表分离，并具备状态清理索引和完整审计时间。
     *
     * @throws Exception 迁移文件不可读
     */
    @Test
    public void writeIntentTableHasRequiredRecoveryColumns() throws Exception {
        String sql = migrationSql();

        assertTrue(sql.contains("CREATE TABLE IF NOT EXISTS `tb_skill_content_write_intent`"));
        assertTrue(sql.contains("`content_ref` VARCHAR(128) NOT NULL"));
        assertTrue(sql.contains("`reservation_token` VARCHAR(128) NOT NULL"));
        assertTrue(sql.contains("`content_hash` VARCHAR(128) NOT NULL"));
        assertTrue(sql.contains("`storage_locator` VARCHAR(2048) NOT NULL"));
        assertTrue(sql.contains("`state` VARCHAR(16) NOT NULL COMMENT 'PENDING/WRITING/CLEANING'"));
        assertTrue(sql.contains("PRIMARY KEY (`content_ref`)"));
        assertTrue(sql.contains("`idx_skill_content_write_intent_state_modified` (`state`, `modified`)"));
        assertTrue(sql.contains("`created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP"));
        assertTrue(sql.contains("`modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"));
    }

    /**
     * 读取工作区中的 V31 MySQL 迁移。
     *
     * @return 迁移 SQL
     * @throws Exception 迁移文件不存在或不可读
     */
    private String migrationSql() throws Exception {
        Path root = Path.of(System.getProperty("maven.multiModuleProjectDirectory",
                Path.of(System.getProperty("user.dir")).toAbsolutePath().toString()));
        while (root != null) {
            Path migration = root.resolve("easyflow-starter/easyflow-starter-all/src/main/resources/"
                    + "db/migration/mysql/V31__mysql_skill_content_write_intent.sql");
            if (Files.isRegularFile(migration)) {
                return Files.readString(migration, StandardCharsets.UTF_8);
            }
            root = root.getParent();
        }
        throw new IllegalStateException("找不到 V31 Skill 内容写入意图迁移");
    }
}
