package com.xxx.amp.magenta.livecodebench;

import com.xxx.amp.magenta.livecodebench.model.TestRun;
import com.xxx.amp.magenta.livecodebench.model.TestStatus;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.List;
import java.util.function.Predicate;

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

public class RunnerTest {

    @Test
    public void testBasicLoading() throws Exception {
        String questionFile = this.getClass()
                .getResource("/StdioTestSuiteTest.json")
                .getFile();

        Runner r = new Runner(questionFile);

        assert r.getClassName()
                .equals("com.xxx.amp.magenta.livecodebench.solution.StrLenSolution");
        assert r.getSuite()
                .getClass()
                .getSimpleName()
                .equals("StdioSuite");
    }

    @Test
    public void testLeetcodeSplitArray() throws Throwable {
        String questionFile = this.getClass()
                .getResource("/LeetcodeSplitArray.json")
                .getFile();

        Runner r = new Runner(questionFile);
        List<TestRun> results = r.run(0);

        assertNoErrors(results);

        FuncCallSuite suite = (FuncCallSuite) r.getSuite();
        assertEquals(List.of(
                        true, false, true, true, true, true, true, true, true, false, true, false, false, true
                ),
                suite.getParsedOutput()
        );

        assert r.getClassName()
                .equals("com.xxx.amp.magenta.livecodebench.solution.LeetcodeCanSplitSolution");
    }

    private void assertNoErrors(List<TestRun> results) throws IOException {
        assertForAllTest(results, x -> x.getStatus() != TestStatus.ERROR);
    }

    private void assertForAllTest(List<TestRun> results, Predicate<TestRun> valid) throws IOException {
        for (TestRun result : results) {
            if (!valid.test(result)) {
                throw new AssertionError("Failed. Input: %s Output: %s".formatted(
                        result.getInput(),
                        result.getOutput()
                ));
            }
        }
    }

    @Test
    public void testLeetcodeRemoveAdjacent() throws Throwable {
        String questionFile = this.getClass()
                .getResource("/RemoveAdjacent.json")
                .getFile();

        Runner r = new Runner(questionFile);
        List<TestRun> results = r.run(0);

        assertNoErrors(results);

        assert r.getClassName()
                .equals("com.xxx.amp.magenta.livecodebench.solution.RemoveAdjacentSolution");
    }

    @Test
    public void testLeetcodeNumberGame() throws Throwable {
        String questionFile = this.getClass()
                .getResource("/NumberGame.json")
                .getFile();

        Runner r = new Runner(questionFile);
        List<TestRun> results = r.run(0);

        assertNoErrors(results);

        assert r.getClassName()
                .equals("com.xxx.amp.magenta.livecodebench.solution.NumberGameSolution");
    }
}
