package terminal;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TerminalHistoryTest {

    private TerminalHistory history;

    private void assertAtBeginning() {
        assertTrue(history.isBeginning());
    }

    private void assertAtEnd() {
        assertTrue(history.isEnd());
    }

    private void assertPrevious(String expected) {
        assertEquals(expected, history.getPreviousLine());
    }

    private void assertNext(String expected) {
        assertEquals(expected, history.getNextLine());
    }

    @Before
    public void setUp() {
        history = new TerminalHistory();
    }

    @After
    public void tearDown() {}

    @Test
    public void historyStartsWithNoLines() {
        assertAtBeginning();
        assertAtEnd();
    }

    @Test
    public void addOneLineToHistory() {
        history.addLine("test line");

        assertPrevious("test line");
        assertAtBeginning();
    }

    @Test
    public void currentLineIsEmpty() {
        history.addLine("one");
        history.getPreviousLine();

        assertNext("");
    }

    @Test
    public void moveBackwards() {
        history.addLine("one");
        history.addLine("two");

        assertPrevious("two");
        assertPrevious("one");
        assertAtBeginning();
    }

    @Test
    public void moveForwards() {
        history.addLine("one");
        history.addLine("two");
        history.getPreviousLine();
        history.getPreviousLine();

        assertNext("two");
        assertNext("");
        assertAtEnd();
    }

    @Test
    public void addedLineGoesAtEndOfHistory() {
        history.addLine("one");
        history.addLine("two");
        history.getPreviousLine();
        history.getPreviousLine();
        history.addLine("three");

        assertPrevious("three");
        assertPrevious("two");
        assertPrevious("one");
        assertAtBeginning();
    }

    @Test
    public void currentLineIsUpdated() {
        history.addLine("one");
        history.updateCurrentLine("purple");
        history.getPreviousLine();

        assertNext("purple");
    }

    @Test
    public void previousLineIsUpdated() {
        history.addLine("one");
        history.addLine("two");
        history.getPreviousLine();
        history.updateCurrentLine("purple");
        history.getPreviousLine();

        assertNext("purple");
    }

    @Test
    public void goingPastFirstLine_KeepsReturningFirstLine() {
        history.addLine("one");
        history.addLine("two");
        history.getPreviousLine();
        history.getPreviousLine();
        history.getPreviousLine();
        history.getPreviousLine();
        history.getPreviousLine();

        assertPrevious("one");
    }

    @Test
    public void goingPastLastLine_KeepsReturningLastLine() {
        history.updateCurrentLine("current");
        history.getNextLine();
        history.getNextLine();
        history.getNextLine();
        history.getNextLine();

        assertNext("current");
    }

}
