package se.kits.gakusei.controller;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import se.kits.gakusei.content.model.Lesson;
import se.kits.gakusei.content.model.Quiz;
import se.kits.gakusei.content.repository.LessonRepository;
import se.kits.gakusei.content.repository.QuizRepository;
import se.kits.gakusei.test_tools.TestTools;
import se.kits.gakusei.util.QuestionHandler;
import se.kits.gakusei.util.QuizHandler;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

@RunWith(MockitoJUnitRunner.class)
public class QuizControllerTest {

    @InjectMocks
    private QuizController quizController;

    @Mock
    private LessonRepository lessonRepository;

    @Mock
    private QuestionHandler questionHandler;

    @Mock
    private QuizRepository quizRepository;

    @Mock
    private QuizHandler quizHandler;

    private String lessonName;
    private List<Quiz> fewQuizzes;
    private List<Quiz> manyQuizzes;
    private int pageSize;
    private String searchString;
    private Quiz quiz;
    private List<HashMap<String, Object>> questions;

    @Before
    public void setUp() throws Exception {
        lessonName = "testLesson";
        fewQuizzes = TestTools.generateQuizzes(5, "Test", "Beskrivning");
        manyQuizzes = TestTools.generateQuizzes(30, "Test", "Beskrivning");
        pageSize = 10;
        searchString = "test";
        quiz = TestTools.generateQuiz();
        questions = new ArrayList<>();
        questions.add(TestTools.createQuestion(quiz, 3));
    }

    @Test
    public void testGetQuizQuestions() {
        String correctData = "quiz_correct";
        String incorrectData = "quiz_incorrect";
        String description = "quiz_question";
        Lesson lesson = TestTools.generateQuizLesson(lessonName, description, correctData, incorrectData);
        Mockito.when(lessonRepository.findByName(lessonName)).thenReturn(lesson);
        List<HashMap<String, Object>> dtoList = Collections.singletonList(TestTools.generateQuestion());
        Mockito.when(questionHandler.createQuizQuestions(lesson.getNuggets())).thenReturn(dtoList);
        ResponseEntity<List<HashMap<String, Object>>> re = quizController.getQuizQuestions(lessonName);

        assertEquals(dtoList, re.getBody());
        assertEquals(200, re.getStatusCodeValue());
    }

    @Test
    public void testGetQuizQuestionsLessonNameNull() {
        Mockito.when(lessonRepository.findByName(lessonName)).thenReturn(null);
        ResponseEntity<List<HashMap<String, Object>>> re = quizController.getQuizQuestions(lessonName);
        assertEquals(null, re.getBody());
        assertEquals(500, re.getStatusCodeValue());
    }

    @Test
    public void testGetAllQuizzesOK() {
        Mockito.when(quizRepository.findAll()).thenReturn(fewQuizzes);
        ResponseEntity<Iterable<Quiz>> re = quizController.getQuizzes();
        assertEquals(fewQuizzes, re.getBody());
        assertEquals(HttpStatus.OK, re.getStatusCode());
    }

    @Test
    public void testGetFirstPageOfQuizzesOK() {
        Pageable pageRequest = new PageRequest(0, pageSize);
        Page<Quiz> firstPage = TestTools.generateQuizzesPage(manyQuizzes, pageRequest);
        Mockito.when(quizRepository.findAll(pageRequest)).thenReturn(firstPage);
        ResponseEntity<Iterable<Quiz>> re = quizController.getQuizzesPage(0);
        assertEquals(firstPage.getContent(), re.getBody());
        assertEquals(HttpStatus.OK, re.getStatusCode());
    }

    @Test
    public void testGetLastPageOfQuizzesOK() {
        int lastPageIndex = manyQuizzes.size() / pageSize;
        Pageable pageRequest = new PageRequest(lastPageIndex, pageSize);
        Page<Quiz> lastPage = TestTools.generateQuizzesPage(manyQuizzes, pageRequest);
        Mockito.when(quizRepository.findAll(pageRequest)).thenReturn(lastPage);
        ResponseEntity<Iterable<Quiz>> re = quizController.getQuizzesPage(lastPageIndex);
        assertEquals(lastPage.getContent(), re.getBody());
        assertEquals(HttpStatus.OK, re.getStatusCode());
    }

    @Test
    public void testGetFirstPageOfQuizzesByNameOK() {
        Pageable pageRequest = new PageRequest(0, pageSize);
        Page<Quiz> firstMatchingPage = TestTools.generateQuizzesPage(manyQuizzes, pageRequest);
        Mockito.when(quizRepository.findByNameContainingIgnoreCase(searchString, pageRequest)).
                thenReturn(firstMatchingPage.getContent());
        ResponseEntity<Iterable<Quiz>> re = quizController.getQuizzesByName(searchString, 0);
        assertEquals(firstMatchingPage.getContent(), re.getBody());
        assertEquals(HttpStatus.OK, re.getStatusCode());
    }

    @Test
    public void testGetQuizNuggetsOK() {
        Mockito.when(quizHandler.getQuizNuggets(quiz.getId())).thenReturn(questions);
        ResponseEntity<List<HashMap<String,Object>>> re = quizController.getQuizNuggets(quiz.getId());
        assertEquals(questions, re.getBody());
        assertEquals(HttpStatus.OK, re.getStatusCode());
    }
}

@@ -1155,64 +1155,8 @@
 y;%0A%0A
-    @Mock%0A    private QuestionHandler questionHandler;%0A%0A
     
@@ -1284,16 +1284,45 @@
 onName;%0A
+    private String quizName;%0A
     priv
@@ -1606,24 +1606,55 @@
 estLesson%22;%0A
+        quizName = %22Testquiz%22;%0A
         fewQ
@@ -2045,255 +2045,8 @@
 ) %7B%0A
-        String correctData = %22quiz_correct%22;%0A        String incorrectData = %22quiz_incorrect%22;%0A        String description = %22quiz_question%22;%0A        Lesson lesson = TestTools.generateQuizLesson(lessonName, description, correctData, incorrectData);%0A
     
@@ -2054,38 +2054,36 @@
    Mockito.when(
-lesson
+quiz
 Repository.findB
@@ -2084,34 +2084,38 @@
 .findByName(
-lesson
+quiz.get
 Name
+()
 )).thenRetur
@@ -2116,22 +2116,20 @@
 nReturn(
-lesson
+quiz
 );%0A     
@@ -2255,22 +2255,18 @@
 n(qu
-estion
+iz
 Handler.
 crea
@@ -2265,45 +2265,43 @@
 ler.
-createQuizQuestions(lesson.getNuggets
+getQuizNuggetsForGakusei(quiz.getId
 ()))
@@ -2409,30 +2409,28 @@
 izQuestions(
-lesson
+quiz
 Name);%0A%0A    

Rewrite test so it works with new format