package com.andrewlalis.perfin.data.impl;

import com.andrewlalis.perfin.data.util.FileUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

/**
 * Tests the {@link FileSystemSavedQueryRepository}, which uses a specific
 * directory under the Perfin profile's content directory for storing SQL
 * queries.
 */
public class FileSystemSavedQueryRepositoryTest {
    private static final Path CONTENT_DIR = Path.of("target", "FileSystemSavedQueryRepositoryTest_content-dir");

    @BeforeEach
    public void setupTestEnvironment() {
        try {
            if (Files.exists(CONTENT_DIR)) {
                FileUtil.deleteDirRecursive(CONTENT_DIR);
            }

            Files.createDirectories(CONTENT_DIR);
            Path queriesDir = CONTENT_DIR.resolve("saved-queries");
            Files.createDirectory(queriesDir);
            Files.writeString(queriesDir.resolve("sample-1.sql"), """
                    SELECT * FROM transaction ORDER BY timestamp DESC;
                    """);
            Files.writeString(queriesDir.resolve("sample-2.sql"), """
                    SELECT COUNT(id)
                    FROM transaction
                    WHERE amount > 1000
                    """);
            Files.writeString(queriesDir.resolve("sample-3.sql"), """
                    SELECT 'Test str';
                    """);
            Files.writeString(queriesDir.resolve("not-a-query.txt"), "not an SQL query!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Test
    public void testGetSavedQueries() {
        var repo = new FileSystemSavedQueryRepository(CONTENT_DIR);
        var queries = repo.getSavedQueries();
        assertEquals(List.of("sample-1", "sample-2", "sample-3"), queries);
    }

    @Test
    public void testGetSavedQueryContent() {
        var repo = new FileSystemSavedQueryRepository(CONTENT_DIR);
        String content = repo.getSavedQueryContent("sample-1");
        assertEquals("SELECT * FROM transaction ORDER BY timestamp DESC;\n", content);

        assertNull(repo.getSavedQueryContent("non-existent-query"));
    }

    @Test
    public void testCreateSavedQuery() {
        var repo = new FileSystemSavedQueryRepository(CONTENT_DIR);
        String name = "sample-4";
        String content = "SELECT AVG(amount) FROM transaction;";
        repo.createSavedQuery(name, content);
        assertTrue(repo.getSavedQueries().contains(name));
        assertEquals(content, repo.getSavedQueryContent(name));
    }

    @Test
    public void testDeleteSavedQuery() {
        var repo = new FileSystemSavedQueryRepository(CONTENT_DIR);
        assertTrue(repo.getSavedQueries().contains("sample-1"));
        repo.deleteSavedQuery("sample-1");
        assertFalse(repo.getSavedQueries().contains("sample-1"));
        repo.deleteSavedQuery("sample-1");
        assertFalse(repo.getSavedQueries().contains("sample-1"));
    }
}
