package fi.helsinki.cs.tmc.cli.command;

import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.containsString;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import fi.helsinki.cs.tmc.cli.Application;
import fi.helsinki.cs.tmc.cli.io.TestIo;
import fi.helsinki.cs.tmc.core.TmcCore;
import fi.helsinki.cs.tmc.core.domain.Course;
import fi.helsinki.cs.tmc.core.domain.Exercise;
import fi.helsinki.cs.tmc.core.domain.ProgressObserver;

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

import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

public class ListExercisesCommandTest {

    Application app;
    TestIo io;
    TmcCore mockCore;

    @Before
    public void setUp() {
        io = new TestIo();
        app = new Application(io);
        mockCore = mock(TmcCore.class);
        app.setTmcCore(mockCore);

        doAnswer(new Answer<Callable<Course>>() {
            @Override
            public Callable<Course> answer(InvocationOnMock invocation) throws Throwable {
                final Course course = (Course)invocation.getArguments()[1];
                return new Callable<Course>() {
                    @Override
                    public Course call() throws Exception {
                        return course;
                    }
                };
            }
        }).when(mockCore).getCourseDetails(any(ProgressObserver.class), any(Course.class));
    }

    @Test
    public void giveMessageIfNoExercisesOnCourse() {
        Callable<List<Course>> callable = new Callable<List<Course>>() {
            @Override
            public List<Course> call() throws Exception {
                Course course = new Course("test-course123");

                ArrayList<Course> tmp = new ArrayList<>();
                tmp.add(course);
                return tmp;
            }
        };
        when(mockCore.listCourses(any(ProgressObserver.class))).thenReturn(callable);

        String[] args = {"list-exercises", "test-course123"};
        app.run(args);
        assertThat(io.out(), containsString("have any exercises"));
    }

    @Test
    public void listExercisesGivesCorrectExercises() {
        Callable<List<Course>> callable = new Callable<List<Course>>() {
            @Override
            public List<Course> call() throws Exception {
                List<Exercise> list = new ArrayList<>();
                list.add(new Exercise("hello-exercise"));
                list.add(new Exercise("cool-exercise"));

                Course course = new Course("test-course123");
                course.setExercises(list);

                ArrayList<Course> tmp = new ArrayList<>();
                tmp.add(course);
                return tmp;
            }
        };
        when(mockCore.listCourses(any(ProgressObserver.class))).thenReturn(callable);

        String[] args = {"list-exercises", "test-course123"};
        app.run(args);
        assertThat(io.out(), containsString("hello-exercise"));
    }

    @Test
    public void emptyArgsGivesAnErrorMessage() {
        when(mockCore.listCourses(any(ProgressObserver.class))).thenReturn(null);
        String[] args = {"list-exercises"};
        app.run(args);
        assertThat(io.out(), containsString("No course specified"));
    }
}

@@ -736,20 +736,17 @@
 il.Array
-List
+s
 ;%0Aimport
@@ -1878,32 +1878,37 @@
         
-Course course = 
+return Arrays.asList(
 new Cour
@@ -1931,129 +1931,9 @@
 23%22)
-;%0A%0A                ArrayList%3CCourse%3E tmp = new ArrayList%3C%3E();%0A                tmp.add(course);%0A                return tmp
+)
 ;%0A  
@@ -2457,36 +2457,33 @@
 %3E list =
- new
  Array
-List%3C%3E();%0A
+s.asList(%0A 
         
@@ -2486,33 +2486,31 @@
             
-list.add(
+       
 new Exercise
@@ -2523,26 +2523,25 @@
 o-exercise%22)
-);
+,
 %0A           
@@ -2549,17 +2549,16 @@
     
-list.add(
+        
 new 
@@ -2712,110 +2712,36 @@
     
-ArrayList%3CCourse%3E tmp = new ArrayList%3C%3E();%0A                tmp.add(course);%0A                return tmp
+return Arrays.asList(course)
 ;%0A  
@@ -3288,11 +3288,544 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void failIfCourseExists() %7B%0A        Callable%3CList%3CCourse%3E%3E callable = new Callable%3CList%3CCourse%3E%3E() %7B%0A            @Override%0A            public List%3CCourse%3E call() throws Exception %7B%0A                return Arrays.asList(new Course(%22hello-exercise%22));%0A            %7D%0A        %7D;%0A        when(mockCore.listCourses(any(ProgressObserver.class))).thenReturn(callable);%0A%0A        String%5B%5D args = %7B%22list-exercises%22, %22abc%22%7D;%0A        app.run(args);%0A        assertThat(io.out(), containsString(%22Course doesn't exist%22));%0A    %7D
 %0A%7D%0A

Add one more test for exercise listing.