package com.easyagents.skill.store.memory;

import com.easyagents.skill.store.SkillContentStage;
import org.junit.Assert;
import org.junit.Test;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;

/**
 * InMemorySkillContentStore 单元测试。
 */
public class InMemorySkillContentStoreTest {

    /**
     * put 返回 sha256 内容引用，且相同内容引用相同。
     */
    @Test
    public void putReturnsStableSha256Ref() {
        InMemorySkillContentStore store = new InMemorySkillContentStore();

        String firstRef = store.put("abc".getBytes(StandardCharsets.UTF_8));
        String secondRef = store.put("abc".getBytes(StandardCharsets.UTF_8));

        Assert.assertTrue(firstRef.startsWith("sha256:"));
        Assert.assertEquals(firstRef, secondRef);
    }

    /**
     * open、readAllBytes 和 exists 正常工作。
     *
     * @throws Exception 读取流失败时抛出
     */
    @Test
    public void openReadAndExists() throws Exception {
        InMemorySkillContentStore store = new InMemorySkillContentStore();
        byte[] bytes = "abc".getBytes(StandardCharsets.UTF_8);

        String contentRef = store.put(bytes);

        Assert.assertTrue(store.exists(contentRef));
        Assert.assertArrayEquals(bytes, store.readAllBytes(contentRef));
        try (InputStream inputStream = store.open(contentRef)) {
            Assert.assertArrayEquals(bytes, inputStream.readAllBytes());
        }
    }

    /**
     * 暂存内容在 commit 前不可见，rollback 后不残留。
     */
    @Test
    public void stageCommitAndRollback() {
        InMemorySkillContentStore store = new InMemorySkillContentStore();
        byte[] bytes = "abc".getBytes(StandardCharsets.UTF_8);

        SkillContentStage rolledBack = store.stage(new java.io.ByteArrayInputStream(bytes), bytes.length);
        Assert.assertFalse(store.exists(rolledBack.getContentRef()));
        store.rollback(rolledBack);
        Assert.assertFalse(store.exists(rolledBack.getContentRef()));

        SkillContentStage committed = store.stage(new java.io.ByteArrayInputStream(bytes), bytes.length);
        String contentRef = store.commit(committed);
        Assert.assertTrue(store.exists(contentRef));
        Assert.assertArrayEquals(bytes, store.readAllBytes(contentRef));
    }

    /**
     * 相同内容按引用计数释放，归零后删除。
     */
    @Test
    public void releaseDeletesOnlyAfterReferenceCountReachesZero() {
        InMemorySkillContentStore store = new InMemorySkillContentStore();
        byte[] bytes = "abc".getBytes(StandardCharsets.UTF_8);

        String first = store.put(bytes);
        String second = store.put(bytes);
        store.release(first);

        Assert.assertTrue(store.exists(second));
        store.release(second);
        Assert.assertFalse(store.exists(second));
    }
}
