package pingis.controllers;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.compress.archivers.ArchiveException;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;
import pingis.entities.ImplementationType;
import pingis.entities.Task;
import pingis.entities.Challenge;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import pingis.entities.TmcSubmission;
import pingis.services.*;
import pingis.utils.EditorTabData;
import pingis.utils.JavaClassGenerator;
import pingis.utils.JavaSyntaxChecker;

@Controller
public class TaskController {

    @Autowired
    ChallengeService challengeService;
    @Autowired
    TaskService taskService;
    @Autowired
    EditorService editorService;

    @Autowired
    private SubmissionPackagingService packagingService;

    @Autowired
    private SubmissionSenderService senderService;

    @RequestMapping(value = "/task/{challengeId}/{taskId}", method = RequestMethod.GET)
    public String task(Model model,
                       @PathVariable Long challengeId,
                       @PathVariable int taskId) {

        Challenge currentChallenge = challengeService.findOne(challengeId);
        Task currentTask = taskService.findTaskInChallenge(challengeId, taskId);
        LinkedHashMap<String, EditorTabData> editorContents = editorService.generateContent(currentTask);

        model.addAttribute("challenge", currentChallenge);
        model.addAttribute("task", currentTask);
        model.addAttribute("editorContents", editorContents);

        String implFileName = JavaClassGenerator.generateImplClassFilename(currentChallenge);
        String testFileName = JavaClassGenerator.generateTestClassFilename(currentChallenge);

        model.addAttribute("implementationFileName", implFileName);
        model.addAttribute("testFileName", testFileName);

        String implCode = "TODO impl";
        String testCode = "TODO test";

        if (currentTask.getType() == ImplementationType.IMPLEMENTATION) {
            implCode = currentTask.getCodeStub();
        } else {
            testCode = currentTask.getCodeStub();
        }

        model.addAttribute("implementationCode", implCode);
        model.addAttribute("testCode", testCode);

        return "task";
    }

    @RequestMapping(value = "/task", method = RequestMethod.POST)
    public RedirectView task(String implementationCode,
                             String testCode,
                             Long challengeId,
                             Integer taskId,
                             RedirectAttributes redirectAttributes) throws IOException, ArchiveException {

        redirectAttributes.addAttribute("challengeId", challengeId);
        redirectAttributes.addAttribute("taskId", taskId);

        Challenge currentChallenge = challengeService.findOne(challengeId);
        Task currentTask = taskService.findTaskInChallenge(challengeId, taskId);

        String checkedCode;

        if (currentTask.getType() == ImplementationType.IMPLEMENTATION) {
            checkedCode = implementationCode;
        } else {
            checkedCode = testCode;
        }

        String[] syntaxErrors = JavaSyntaxChecker.parseCode(checkedCode);

        if (syntaxErrors != null) {
            redirectAttributes.addFlashAttribute("errors", syntaxErrors);
            redirectAttributes.addFlashAttribute("code", checkedCode);

            return new RedirectView("/task/{challengeId}/{taskId}");
        }

        Map<String, byte[]> files = new HashMap<>();

        String implFileName = JavaClassGenerator.generateImplClassFilename(currentChallenge);
        String testFileName = JavaClassGenerator.generateTestClassFilename(currentChallenge);

        files.put(implFileName, implementationCode.getBytes());
        files.put(testFileName, testCode.getBytes());

        byte[] packaged = packagingService.packageSubmission(files);
        TmcSubmission submission = senderService.sendSubmission(packaged);

        redirectAttributes.addAttribute("submission", submission);

        return new RedirectView("/feedback");
    }


    @RequestMapping("/feedback")
    public String feedback(Model model) {
        model.addAttribute("feedback", "Good work!");
        return "feedback";
    }


}

@@ -2674,24 +2674,716 @@
 sk%22;%0A    %7D%0A%0A
+    // TODO: This should actually be a separate service...%0A    private TmcSubmission submitToTmc(Challenge challenge, String implementationCode, String testCode)%0A            throws IOException, ArchiveException %7B%0A        Map%3CString, byte%5B%5D%3E files = new HashMap%3C%3E();%0A%0A        String implFileName = JavaClassGenerator.generateImplClassFilename(challenge);%0A        String testFileName = JavaClassGenerator.generateTestClassFilename(challenge);%0A%0A        files.put(implFileName, implementationCode.getBytes());%0A        files.put(testFileName, testCode.getBytes());%0A%0A        byte%5B%5D packaged = packagingService.packageSubmission(files);%0A        return senderService.sendSubmission(packaged);%0A    %7D%0A%0A
     @Request
@@ -3436,16 +3436,16 @@
 d.POST)%0A
-
     publ
@@ -3742,137 +3742,8 @@
  %7B%0A%0A
-        redirectAttributes.addAttribute(%22challengeId%22, challengeId);%0A        redirectAttributes.addAttribute(%22taskId%22, taskId);%0A%0A
     
@@ -3892,24 +3892,183 @@
 , taskId);%0A%0A
+        redirectAttributes.addAttribute(%22challengeId%22, currentChallenge.getId());%0A        redirectAttributes.addAttribute(%22taskId%22, currentTask.getTaskId());%0A%0A
         Stri
@@ -4617,506 +4617,95 @@
     
-Map%3CString, byte%5B%5D%3E files = new HashMap%3C%3E();%0A%0A        String implFileName = JavaClassGenerator.generateImplClassFilename(currentChallenge);%0A        String testFileName = JavaClassGenerator.generateTestClassFilename(currentChallenge);%0A%0A        files.put(implFileName, implementationCode.getBytes());%0A        files.put(testFileName, testCode.getBytes());%0A%0A        byte%5B%5D packaged = packagingService.packageSubmission(files);%0A        TmcSubmission submission = senderService.sendSubmission(packaged);%0A
+TmcSubmission submission = submitToTmc(currentChallenge, implementationCode, testCode);
 %0A   
@@ -4815,24 +4815,23 @@
 back%22);%0A
+
     %7D%0A%0A
-%0A
     @Req

Fix checkstyle issues with TaskController.