package com.optage.parser;

import com.optage.model.TestInfo;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;

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

@DisplayName("Test Detection - is_test Flag")
class TestDetectorTest {
    private TestDetector detector = new TestDetector();

    @Test
    @DisplayName("T1a: Detect @Test annotation")
    void testDetectTestAnnotation() {
        String code = """
            @Test
            public void testUserCreation() {
                // test code
            }
            """;

        TestInfo info = detector.detect("UserTest", "src/main/java/UserTest.java", code);

        assertThat(info.isTest()).isTrue();
        assertThat(info.getDetectionSignals()).contains("annotation:@Test");
    }

    @Test
    @DisplayName("T1b: Detect @Before annotation")
    void testDetectBeforeAnnotation() {
        String code = """
            @Before
            public void setUp() {
                // setup code
            }
            """;

        TestInfo info = detector.detect("UserTest", "src/test/java/UserTest.java", code);

        assertThat(info.isTest()).isTrue();
    }

    @Test
    @DisplayName("T1c: Detect TestCase superclass")
    void testDetectTestCaseSuperclass() {
        String code = "public class UserTest extends TestCase { }";

        TestInfo info = detector.detect("UserTest", "src/main/java/UserTest.java", code);

        assertThat(info.isTest()).isTrue();
        assertThat(info.getDetectionSignals()).contains("superclass:TestCase");
    }

    @Test
    @DisplayName("T2a: Detect test by path (src/test/java)")
    void testDetectByTestPath() {
        String code = "public class User { }";

        TestInfo info = detector.detect("User", "src/test/java/UserTest.java", code);

        assertThat(info.isTest()).isTrue();
        assertThat(info.getDetectionSignals()).contains("path:src/test/java/UserTest.java");
    }

    @Test
    @DisplayName("T2b: Detect test by path (tests/)")
    void testDetectByTestsPath() {
        String code = "public class UserTest { }";

        TestInfo info = detector.detect("UserTest", "tests/unit/test_user.py", code);

        assertThat(info.isTest()).isTrue();
    }

    @Test
    @DisplayName("T2c: Detect test by path (__tests__/)")
    void testDetectByTestsUnderscorePath() {
        String code = "export function testUser() { }";

        TestInfo info = detector.detect("user", "src/__tests__/user.test.js", code);

        assertThat(info.isTest()).isTrue();
    }

    @Test
    @DisplayName("T2d: Detect test by filename pattern")
    void testDetectByFilenamePattern() {
        String[] testFiles = {
            "UserTest.java",
            "test_user.py",
            "user.test.js"
        };

        for (String filename : testFiles) {
            TestInfo info = detector.detect("Test", "src/" + filename, "");
            assertThat(info.isTest()).isTrue();
        }
    }

    @Test
    @DisplayName("CR1: Path priority - TestHelper in main is not test")
    void testPathPriorityMainPath() {
        String code = "public class TestHelper { }";

        TestInfo info = detector.detect("TestHelper", "src/main/java/TestHelper.java", code);

        assertThat(info.isTest()).isFalse();
    }

    @Test
    @DisplayName("CR2: Annotation override - @Test in main is test")
    void testAnnotationOverride() {
        String code = """
            @Test
            public class UserTest {
                public void test() { }
            }
            """;

        TestInfo info = detector.detect("UserTest", "src/main/java/UserTest.java", code);

        assertThat(info.isTest()).isTrue();
    }

    @Test
    @DisplayName("CR3: Path authoritative - test path without @Test is test")
    void testPathAuthoritative() {
        String code = "public class User { }";

        TestInfo info = detector.detect("User", "src/test/java/User.java", code);

        assertThat(info.isTest()).isTrue();
    }

    @Test
    @DisplayName("CR4: No signals - default is not test")
    void testDefaultNotTest() {
        String code = "public class User { }";

        TestInfo info = detector.detect("User", "src/main/java/User.java", code);

        assertThat(info.isTest()).isFalse();
    }
}