package com.twu.biblioteca;


import com.twu.mockmodels.TestInputReader;
import com.twu.mockmodels.TestOutputWriter;
import com.twu.model.menuoption.InvalidMenuOption;
import com.twu.model.menuoption.ListBooksMenuOption;
import com.twu.model.menuoption.MenuOption;
import com.twu.io.output.ConsoleOutput;
import com.twu.model.menuoption.QuitMenuOption;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

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

public class LibraryTest {

    private Library library;

    @Before
    public void setUp(){
        library = new Library();
    }

    private ConsoleOutput getWelcomeMessageOutput() {
        List<String> expectedWelcomeMessage = new ArrayList<>();
        expectedWelcomeMessage.add("Hello User! Welcome to Biblioteca! :)\n");
        return new ConsoleOutput(expectedWelcomeMessage);
    }

    @Test
    public void firstMessageForUserShouldBeWelcomeMessage() {
        ConsoleOutput expectedWelcomeMessageOutput = getWelcomeMessageOutput();
        TestOutputWriter outputWriter = new TestOutputWriter();
        int firstOutputIndex = 0;

        library.openLibrary(outputWriter, new TestInputReader(null));

        ArrayList<ConsoleOutput> outputMessages = outputWriter.getOutputMessages();
        ConsoleOutput welcomeMessageOutput = outputMessages.get(firstOutputIndex);
        assertEquals(expectedWelcomeMessageOutput, welcomeMessageOutput);
    }

    @Test
    public void secondMessageForUserShouldBeMenu() {
        ConsoleOutput expectedMenuOptionOutput = getMenuOptions();
        TestOutputWriter outputWriter = new TestOutputWriter();
        int secondOutputIndex = 1;

        library.openLibrary(outputWriter, new TestInputReader(null));

        ArrayList<ConsoleOutput> outputMessages = outputWriter.getOutputMessages();
        ConsoleOutput menuOptionOutput = outputMessages.get(secondOutputIndex);
        assertEquals(expectedMenuOptionOutput, menuOptionOutput);
    }

    private ConsoleOutput getMenuOptions() {
        List<String> expectedMenuOptions = new ArrayList<>();
        expectedMenuOptions.add("Menu\n");
        expectedMenuOptions.add("\t1. List Books");
        expectedMenuOptions.add("\t2. Quit");
        expectedMenuOptions.add("\nPlease enter your choice : ");
        return new ConsoleOutput(expectedMenuOptions);
    }

    @Test
    public void shouldGetListBooksMenuOptionWhenUserSelectsListBooksMenuOption() {
        String listBooksMenuOption = "1";

        MenuOption menuOption = library.getMenuOptionForUserChoice(listBooksMenuOption);

        assertTrue(menuOption instanceof ListBooksMenuOption);
    }

    @Test
    public void shouldGetQuitMenuOptionWhenUserSelectsQuitMenuOption() {
        String quitMenuOption = "2";

        MenuOption menuOption = library.getMenuOptionForUserChoice(quitMenuOption);

        assertTrue(menuOption instanceof QuitMenuOption);
    }

    @Test
    public void shouldGetInvalidMenuOptionWhenUserSelectsInvalidMenuOption() {
        String invalidMenuOption = "0";

        MenuOption menuOption = library.getMenuOptionForUserChoice(invalidMenuOption);

        assertTrue(menuOption instanceof InvalidMenuOption);
    }

    @Test
    public void shouldAcknowledgeMenuOptionSelectedByUser() {
        String menuOptionInput = "1";
        List<String> expectedMenuOptionAcknowledgement = new ArrayList<>();
        expectedMenuOptionAcknowledgement.add("List Books");
        ConsoleOutput expectedMenuOptionAcknowledgementOutput = new ConsoleOutput
                (expectedMenuOptionAcknowledgement);
        TestOutputWriter outputWriter = new TestOutputWriter();

        library.openLibrary(outputWriter, new TestInputReader(menuOptionInput));
        ArrayList<ConsoleOutput> outputMessages = outputWriter.getOutputMessages();
        ConsoleOutput menuOptionAcknowledgementOutput = outputMessages.get(2);

        assertEquals(expectedMenuOptionAcknowledgementOutput, menuOptionAcknowledgementOutput);
    }

    @Test
    public void shouldPrintErrorMessageWhenInvalidMenuOptionIsSelected() {
        String menuOptionInput = "-1";
        List<String> expectedMenuOptionAcknowledgement = new ArrayList<>();
        expectedMenuOptionAcknowledgement.add("Invalid Menu Option Selected");
        ConsoleOutput expectedMenuOptionAcknowledgementOutput = new ConsoleOutput
                (expectedMenuOptionAcknowledgement);
        TestOutputWriter outputWriter = new TestOutputWriter();

        library.openLibrary(outputWriter, new TestInputReader(menuOptionInput));
        ArrayList<ConsoleOutput> outputMessages = outputWriter.getOutputMessages();
        ConsoleOutput menuOptionAcknowledgementOutput = outputMessages.get(2);

        assertEquals(expectedMenuOptionAcknowledgementOutput, menuOptionAcknowledgementOutput);
    }

}

@@ -964,49 +964,65 @@
 oid 
-firstMessageForUserShouldBeWelcomeMessage
+userShouldBeGreetedWithWelcomeMessageOnApplicationStartup
 () %7B
@@ -1550,40 +1550,45 @@
 oid 
-secondMessageForUserShouldBeMenu
+userShouldGetAMenuAfterWelcomeMessage
 () %7B
@@ -2574,17 +2574,16 @@
  = %221%22;%0A
-%0A
         
@@ -2655,33 +2655,32 @@
 oksMenuOption);%0A
-%0A
         assertTr
@@ -2853,17 +2853,16 @@
  = %222%22;%0A
-%0A
         
@@ -2929,33 +2929,32 @@
 uitMenuOption);%0A
-%0A
         assertTr
@@ -3131,17 +3131,16 @@
  = %220%22;%0A
-%0A
         
@@ -3218,17 +3218,16 @@
 ption);%0A
-%0A
         
@@ -3365,33 +3365,42 @@
 %0A        String 
-m
+listBooksM
 enuOptionInput =
@@ -3388,29 +3388,24 @@
 ksMenuOption
-Input
  = %221%22;%0A    
@@ -3791,33 +3791,42 @@
 TestInputReader(
-m
+listBooksM
 enuOptionInput))
@@ -3810,37 +3810,32 @@
 tBooksMenuOption
-Input
 ));%0A        Arra
@@ -4189,17 +4189,24 @@
  String 
-m
+invalidM
 enuOptio
@@ -4206,21 +4206,16 @@
 nuOption
-Input
  = %22-1%22;
@@ -4632,17 +4632,24 @@
 tReader(
-m
+invalidM
 enuOptio
@@ -4649,21 +4649,16 @@
 nuOption
-Input
 ));%0A    

Refactor tests to identify the order in which messages should be shown to user