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.anyObject;
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 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);
    }

    @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((ProgressObserver) anyObject())).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((ProgressObserver) anyObject())).thenReturn(callable);
        String[] args = {"list-exercises", "test-course123"};
        app.run(args);
        assertThat(io.out(), containsString("hello-exercise"));
    }

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

@@ -178,22 +178,60 @@
 hers.any
-Object
+;%0Aimport static org.mockito.Mockito.doAnswer
 ;%0Aimport
@@ -629,16 +629,101 @@
 .Test;%0A%0A
+import org.mockito.invocation.InvocationOnMock;%0Aimport org.mockito.stubbing.Answer;%0A%0A
 import j
@@ -1077,16 +1077,580 @@
 ckCore);
+%0A%0A        doAnswer(new Answer%3CCallable%3CCourse%3E%3E() %7B%0A            @Override%0A            public Callable%3CCourse%3E answer(InvocationOnMock invocation) throws Throwable %7B%0A                final Course course = (Course)invocation.getArguments()%5B1%5D;%0A                return new Callable%3CCourse%3E() %7B%0A                    @Override%0A                    public Course call() throws Exception %7B%0A                        return course;%0A                    %7D%0A                %7D;%0A            %7D%0A        %7D).when(mockCore).getCourseDetails(any(ProgressObserver.class), any(Course.class));
 %0A    %7D%0A%0A
@@ -2065,33 +2065,32 @@
    %7D%0A        %7D;%0A
-%0A
         when(moc
@@ -2099,32 +2099,35 @@
 ore.listCourses(
+any
 (ProgressObserve
@@ -2123,36 +2123,30 @@
 ressObserver
-) anyObject(
+.class
 ))).thenRetu
@@ -2151,32 +2151,33 @@
 turn(callable);%0A
+%0A
         String%5B%5D
@@ -2962,17 +2962,16 @@
      %7D;%0A
-%0A
         
@@ -2988,32 +2988,35 @@
 ore.listCourses(
+any
 (ProgressObserve
@@ -3012,36 +3012,30 @@
 ressObserver
-) anyObject(
+.class
 ))).thenRetu
@@ -3044,24 +3044,25 @@
 (callable);%0A
+%0A
         Stri
@@ -3298,16 +3298,19 @@
 Courses(
+any
 (Progres
@@ -3322,20 +3322,14 @@
 rver
-) anyObject(
+.class
 ))).

Fix the list course tests.