/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.csu.sdmx.web.controllers;

import cz.csu.sdmx.dao.LogicConditionsDao;
import cz.csu.sdmx.dao.ValidationResultsDao;
import cz.csu.sdmx.validation.SDMXValidator;
import cz.csu.sdmx.constants.URL;
import cz.csu.sdmx.validation.model.ValidationResult;
import cz.csu.sdmx.constants.JSP;
import cz.csu.sdmx.constants.SESSION;
import cz.csu.sdmx.validation.model.LogicCondition;
import cz.csu.sdmx.validation.model.ValidationError;
import cz.csu.sdmx.web.forms.ValidatorForm;
import cz.csu.sdmx.web.validators.ValidatorFormValidator;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

/**
 *
 * @author themi
 */
@Controller
public class ValidatorController extends BaseController{
    
    @Autowired
    private ValidationResultsDao resultsDao;
    
    @Autowired
    private LogicConditionsDao conditionsDao;
    
    @RequestMapping(value = URL.VALIDATOR, method = RequestMethod.GET)
    public String index(Model model) { 
        
        model.addAttribute(new ValidatorForm());
        
        return JSP.VALIDATOR;
    }
    
    @RequestMapping(value = URL.VALIDATION_INFO, method = RequestMethod.POST)
    public @ResponseBody ModelAndView getValidationInfo() {
        ValidationResult validationResult = (ValidationResult) session.getAttribute(SESSION.VALIDATION_RESULT);
        if(validationResult != null){
            ModelAndView modelAndView = new ModelAndView(JSP.VALIDATION_RESULT_ONLY);
            modelAndView.addObject("validationResult", validationResult);
            return modelAndView;
        }
            
        return null;
    }
    
    @RequestMapping(value = URL.VALIDATOR_VALIDATE, method = RequestMethod.POST)
    public @ResponseBody Object validate(
            @ModelAttribute ValidatorForm validatorForm, BindingResult result, HttpServletResponse response) {
        //validate supplied form with dsd and data files
        ValidatorFormValidator formValidator = new ValidatorFormValidator();
        formValidator.validate(validatorForm, result);
        if(result.hasErrors())
            return null;
        
        SDMXValidator validator = new SDMXValidator(conditionsDao);
        ValidationResult validationResult = validator.getValidationResult();
        //add validation result to session for user view updating
        session.setAttribute(SESSION.VALIDATION_RESULT, validationResult);
        try{
            MultipartFile dataFile = validatorForm.getSDMXDataFile();
            validationResult.setDataFilename(dataFile.getOriginalFilename());
            
            List<MultipartFile> dsdFiles = validatorForm.getDsdFiles();

            //add DSDs to validator
            for(MultipartFile dsdFile : dsdFiles){
                String name = dsdFile.getOriginalFilename();
                InputStream is = dsdFile.getInputStream();

                validator.addDsd(name, is);
            }

            //if nothing wrong with DSDs, validate data
            if(!validationResult.hasErrors())
                validator.validate(dataFile.getOriginalFilename(), dataFile.getInputStream()); 

            resultsDao.insert(validationResult);
        
        }catch(Exception ex){
            //if any unexpected error occured, add validation error
            ex.printStackTrace();
            ValidationError error = new ValidationError();
            error.setErrorCode("UNEXPECTED");
            error.setText(ex.toString());
            error.setType(ValidationError.FATAL);
        }
        
        session.removeAttribute(SESSION.VALIDATION_RESULT);
        
        //create view of validation result
        ModelAndView mw = new ModelAndView(JSP.VALIDATION_RESULT_ONLY);
        
        mw.addObject("validationResult", validationResult);
        List<LogicCondition> lcList = new ArrayList<>();
        //get logic conditions by detected DSDs
        for(String dsd : validationResult.getDsdList())
            lcList.addAll(conditionsDao.getByDsdUrn(dsd));
        
        mw.addObject("conditions", lcList);
        return mw;
    } 

}
