package no.valg.valgnatt.backend;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import no.valg.valgnatt.backend.rapport.MainRapport;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.context.support.WebApplicationContextUtils;

@SuppressWarnings("squid:MethodCyclomaticComplexity") // doGetOrPost har høy syklomatisk kompleksitet, men er likevel lett å forstå
public class ControlServlet extends HttpServlet {

	private static final Logger LOG = LogManager.getLogger(ControlServlet.class);

	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGetOrPost(req, resp);
	}

	private void doGetOrPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		try {
			MainBackend mainBackend = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()).getBean(MainBackend.class);
			MainRapport mainRapport = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()).getBean(MainRapport.class);
			String action = req.getParameter("action");
			String result = "OK";
			if ("setPrognosis".equalsIgnoreCase(action)) {
				mainBackend.setØnsketBeregningsmetode(MainBackend.Beregningsmetode.PROGNOSE);
			} else if ("setActual".equalsIgnoreCase(action)) {
				mainBackend.setØnsketBeregningsmetode(MainBackend.Beregningsmetode.OPPTALTESTEMMER);
			} else if ("setSuspend".equalsIgnoreCase(action)) {
				mainBackend.setØnsketKjøreTilstand(MainBackend.KjøreTilstand.PAUSE);
			} else if ("setResume".equalsIgnoreCase(action)) {
				mainBackend.setØnsketKjøreTilstand(MainBackend.KjøreTilstand.NORMAL);
			} else if (action.startsWith("nullstill")) {
				result = mainBackend.nullstill();
			} else if ("opphevMediaSperrefrist".equals(action)) {
				mainBackend.opphevMediaSperrefrist();
			} else if ("innforMediaSperrefrist".equals(action)) {
				mainBackend.innførMediaSperrefrist();
			} else if ("opphevOffentligSperrefrist".equals(action)) {
				mainBackend.opphevOffentligSperrefrist();
			} else if ("innforOffentligSperrefrist".equals(action)) {
				mainBackend.innførOffentligSperrefrist();
			} else if ("rekonfigurer".equals(action)) {
				result = mainBackend.rekonfigurer();
			} else if (action.startsWith("recalculate")) {
				int kommandoLengde = "recalculate".length();
				mainBackend.beOmRekalkulering(action.length() > kommandoLengde ? action.substring(kommandoLengde) : null);
			} else if (action.startsWith("eksport")) {
				mainBackend.eksporter();
			} else if (action.startsWith("mottakHarOppdatertSb")) {
				mainBackend.beOmOppdateringAvStemmeberettigede();
			} else if ("getTotalRefId".equalsIgnoreCase(action)) {
				result = Integer.toString(mainBackend.getTotalRefId());
			} else if ("getPendingRefId".equalsIgnoreCase(action)) {
				result = Integer.toString(mainBackend.getPendingRefid());
			} else if ("rekalkuleringPågår".equalsIgnoreCase(action)) {
				result = Boolean.toString(mainBackend.rekalkuleringPågår());
			} else if ("erRapportSynket".equalsIgnoreCase(action)) {
				result = Boolean.toString(mainRapport.erRapporterSynketTilAlleKlienter());
			} else if (action.startsWith("alleRapporter")) {
				result = "" + mainRapport.rapporter2JsonSamlerapport(0); // skriver ut alle rapporter som vi har
			} else {
				res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
				return;
			}
			print(res, result);
		} catch (Exception e) {
			String feilmelding = "Feil oppstod: " + e.getMessage();
			LOG.error(feilmelding, e);
			print(res, feilmelding);
		}
	}

	private void print(HttpServletResponse res, String result) throws IOException {
		res.setContentType("text/plain");
		PrintWriter out = res.getWriter();
		out.println(result);
		out.close();
	}

	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGetOrPost(req, resp);
	}

}
