package scanner;

import static org.junit.Assert.assertEquals;
import static testutil.TestUtilities.createInputStreamFromString;

import java.io.InputStream;

import org.junit.Test;

import file.FilePosition;

public class LispScannerTextTest {

    private void assertTokenTextMatches(String input, String[] expectedTextList) {
        LispScanner lispScanner = createLispScanner(input);

        for (String expectedText : expectedTextList)
            assertEquals(expectedText, lispScanner.getNextToken().getText());
    }

    private void assertTokenTextMatches(String input, String expectedText) {
        LispScanner lispScanner = createLispScanner(input);

        assertEquals(expectedText, lispScanner.getNextToken().getText());
    }

    private LispScanner createLispScanner(String input) {
        InputStream stringInputStream = createInputStreamFromString(input);

        return new LispScanner(stringInputStream, "testFile");
    }

    private void assertInputFileNameMatches(String input, String expectedInputFileName) {
        InputStream stringInputStream = createInputStreamFromString(input);
        LispScanner lispScanner = new LispScanner(stringInputStream, expectedInputFileName);
        FilePosition tokenPosition = lispScanner.getNextToken().getPosition();

        assertEquals(expectedInputFileName, tokenPosition.getFileName());
    }

    @Test
    public void givenEmptyStream_RecordsCorrectFileName() {
        String input = "";
        String expectedFileName = "testFileName";

        assertInputFileNameMatches(input, expectedFileName);
    }

    @Test
    public void givenParenthesis_RecordsCorrectText() {
        String input = "()";
        String[] expected = { "(", ")" };

        assertTokenTextMatches(input, expected);
    }

    @Test
    public void givenQuote_RecordsCorrectText() {
        String input = "'";
        String expected = "'";

        assertTokenTextMatches(input, expected);
    }

    @Test
    public void givenEof_ReordsCorrectText() {
        String input = "";
        String expected = "EOF";

        assertTokenTextMatches(input, expected);
    }

    @Test
    public void givenIdentifier_RecordsCorrectText() {
        String input = "identifier";

        assertTokenTextMatches(input, input);
    }

    @Test
    public void givenNumber_RecordsCorrectText() {
        String input = "192837456";

        assertTokenTextMatches(input, input);
    }

    @Test
    public void givenString_RecordsCorrectText() {
        String input = "\"String!!! \n More... \"";

        assertTokenTextMatches(input, input);
    }

    @Test
    public void givenNumberFollowedByComment_RecordsCorrectText() {
        String input = "192837456;comment";
        String expected = "192837456";

        assertTokenTextMatches(input, expected);
    }

    @Test
    public void givenIdentifiersWithCommentBetween_RecordsCorrectText() {
        String input = "abc123;comment\nabc222";
        String[] expected = { "abc123", "abc222" };

        assertTokenTextMatches(input, expected);
    }

    @Test
    public void givenBackTickExpression_RecordsCorrectText() {
        String input = "`(list ,a ,@b)";
        String[] expected = { "`", "(", "list", ",", "a", ",", "@", "b", ")" };

        assertTokenTextMatches(input, expected);
    }

}
