package de.linkvt.bachelor.web;

import de.linkvt.bachelor.features.Feature;
import de.linkvt.bachelor.generator.OntologyGenerator;
import de.linkvt.bachelor.persistence.StoredGeneration;
import de.linkvt.bachelor.persistence.StoredGenerationRepository;
import de.linkvt.bachelor.web.converters.message.OntologySyntax;
import de.linkvt.bachelor.web.converters.parameter.FeatureParameterMapping;
import de.linkvt.bachelor.web.dtos.FeatureDto;
import de.linkvt.bachelor.web.dtos.FormatDto;

import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletResponse;

@RestController
public class GeneratorController {

  private ApplicationContext applicationContext;
  private FeatureParameterMapping featureMapping;
  private StoredGenerationRepository repository;

  @Autowired
  public GeneratorController(ApplicationContext applicationContext, FeatureParameterMapping featureMapping, StoredGenerationRepository repository) {
    this.applicationContext = applicationContext;
    this.featureMapping = featureMapping;
    this.repository = repository;
  }

  @RequestMapping("/ontology")
  public OWLOntology ontology() throws OWLOntologyCreationException {
    return ontology(featureMapping.getAll());
  }

  @RequestMapping(value = "/ontology", params = "features")
  public OWLOntology ontology(@RequestParam("features") List<Feature> features) {
    OntologyGenerator generator = getBean(OntologyGenerator.class);

    generator.addFeatures(features);

    return generator.generate();
  }

  @RequestMapping(value = "/ontology", params = "features", method = RequestMethod.POST)
  public void storeAndRedirect(HttpServletResponse response, @RequestParam("features") List<Feature> features) throws IOException {
    List<String> tokens = features.stream().map(Feature::getToken).collect(Collectors.toList());
    StoredGeneration generation = repository.save(new StoredGeneration(tokens));

    response.sendRedirect("/ontology/" + generation.getId());
  }

  @RequestMapping(value = "/ontology-store", params = "features", method = RequestMethod.GET)
  public void devStoreAndRedirect(HttpServletResponse response, @RequestParam("features") List<Feature> features) throws IOException {
    storeAndRedirect(response, features);
  }

  @RequestMapping("/ontology/{id}")
  public OWLOntology ontologyFromId(@PathVariable("id") Long id) {
    StoredGeneration storedGeneration = repository.findOne(id);
    if (storedGeneration == null) {
      throw new IllegalArgumentException("No generation stored for the passed id.");
    }

    List<Feature> usedFeatures = featureMapping.get(storedGeneration.getParameters());

    return ontology(usedFeatures);
  }

  private <T> T getBean(Class<T> clazz) {
    return applicationContext.getBean(clazz);
  }

  @RequestMapping("/features")
  public List<FeatureDto> features() {
    List<Feature> features = featureMapping.getAll();

    return features.stream().map(FeatureDto::new).collect(Collectors.toList());
  }

  @RequestMapping("/formats")
  public List<FormatDto> formats() {
    List<OntologySyntax> syntaxes = Arrays.asList(OntologySyntax.values());

    return syntaxes.stream().map(FormatDto::new).collect(Collectors.toList());
  }

}

@@ -2218,20 +2218,27 @@
  public 
-void
+OWLOntology
  storeAn
@@ -2234,32 +2234,32 @@
 ogy storeAnd
-Redirect
+Generate
 (HttpServlet
@@ -2544,21 +2544,32 @@
 nse.
-sendRedirect(
+addHeader(%22Short-Path%22, 
 %22/on
@@ -2595,24 +2595,56 @@
 on.getId());
+%0A%0A    return ontology(features);
 %0A  %7D%0A%0A  @Req
@@ -2744,12 +2744,19 @@
 lic 
-void
+OWLOntology
  dev
@@ -2763,24 +2763,24 @@
 StoreAnd
-Redirect
+Generate
 (HttpSer
@@ -2877,24 +2877,31 @@
 n %7B%0A    
+return 
 storeAnd
 Redirect
@@ -2896,16 +2896,16 @@
 eAnd
-Redirect
+Generate
 (res

Set header instead of redirectin on saving