package click.kamil.springstatemachineexporter.analysis.util;

import org.junit.jupiter.api.Test;

import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;

public class PlaceholderResolverTest {

    @Test
    void testSimpleResolution() {
        Map<String, String> props = Map.of("app.path", "/api/v1");
        String result = PlaceholderResolver.resolve("${app.path}", props);
        assertThat(result).isEqualTo("/api/v1");
    }

    @Test
    void testMultiplePlaceholders() {
        Map<String, String> props = Map.of("host", "localhost", "port", "8080");
        String result = PlaceholderResolver.resolve("http://${host}:${port}/api", props);
        assertThat(result).isEqualTo("http://localhost:8080/api");
    }

    @Test
    void testDefaultValue() {
        Map<String, String> props = Map.of();
        String result = PlaceholderResolver.resolve("${missing:/default}", props);
        assertThat(result).isEqualTo("/default");
    }

    @Test
    void testRecursiveResolution() {
        Map<String, String> props = Map.of(
                "base", "/api",
                "version", "v1",
                "full", "${base}/${version}"
        );
        String result = PlaceholderResolver.resolve("${full}/users", props);
        assertThat(result).isEqualTo("/api/v1/users");
    }

    @Test
    void testCycleDetection() {
        Map<String, String> props = Map.of(
                "a", "${b}",
                "b", "${a}"
        );
        // Should not throw StackOverflowError
        String result = PlaceholderResolver.resolve("${a}", props);
        // It should keep the unresolvable placeholder in case of cycle
        assertThat(result).isEqualTo("${a}");
    }

    @Test
    void testMixedContent() {
        Map<String, String> props = Map.of("name", "world");
        String result = PlaceholderResolver.resolve("Hello ${name}!", props);
        assertThat(result).isEqualTo("Hello world!");
    }

    @Test
    void testUnresolvablePlaceholder() {
        Map<String, String> props = Map.of();
        String result = PlaceholderResolver.resolve("${unknown}", props);
        assertThat(result).isEqualTo("${unknown}");
    }
}
