package com.aps.demo;

import com.aps.common.util.redis.RedisUtils;
import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Schedule.SceneChromsome;
import com.aps.service.plan.SceneService;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;

import java.io.File;
import java.util.concurrent.atomic.AtomicReference;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class SceneServiceVersionTest {

    private final String sceneId = "VERSION_TEST_" + System.nanoTime();

    @AfterEach
    void cleanVersionFiles() {
        File resultDir = new File("result");
        File[] files = resultDir.listFiles((dir, name) -> name.startsWith("chromosome_result_" + sceneId + "_"));
        if (files == null) {
            return;
        }
        for (File file : files) {
            file.delete();
        }
    }

    @Test
    void undoAndRedoKeepInsertAndMoveAsSeparateVersions() {
        AtomicReference<SceneChromsome> sceneState = new AtomicReference<>();
        RedisUtils redisUtils = mock(RedisUtils.class);
        when(redisUtils.get(anyString())).thenAnswer(invocation -> sceneState.get());
        doAnswer(invocation -> {
            sceneState.set(invocation.getArgument(1));
            return null;
        }).when(redisUtils).set(anyString(), any());

        SceneService sceneService = new SceneService();
        ReflectionTestUtils.setField(sceneService, "redisUtils", redisUtils);

        Chromosome inserted = new Chromosome();
        inserted.setGenerateType("inserted");
        assertTrue(sceneService.saveChromosomeToFile(inserted, sceneId));

        Chromosome moved = sceneService.loadChromosomeFromFile(sceneId);
        moved.setGenerateType("moved");
        assertTrue(sceneService.saveChromosomeToFile(moved, sceneId));

        Chromosome undone = sceneService.moveChromosome(sceneId, 0);
        assertNotNull(undone);
        assertEquals(1, undone.getVersion());
        assertEquals("inserted", undone.getGenerateType());

        Chromosome redone = sceneService.revertVersion(sceneId, 2);
        assertNotNull(redone);
        assertEquals(2, redone.getVersion());
        assertEquals("moved", redone.getGenerateType());
    }
}
