package no.valg.valgnatt.frontend;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

/**
 * Servlet'en mottar innkommende forespørsler fra evt. klienter (media/valgresultat.no/simulator/etc.)
 */
public class FrontendServlet extends HttpServlet {

	private static final Logger LOG = LogManager.getLogger(FrontendServlet.class);
	private static final int HTTP_RETUR_269 = 269;

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

	private void doGetOrPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		Kontroller kontroller = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()).getBean(Kontroller.class);
		String reqPath = req.getPathInfo();
		Charset tegnsett = StandardCharsets.UTF_8;
		try {
			if (reqPath == null) {
				reqPath = req.getServletPath();
			}
			String path = reqPath.substring(reqPath.indexOf("/") + 1);

			String result;

			if ("simrapporter".equals(path)) {
				result = kontroller.getSimRapporter();
			} else if ("sok".equals(path)) {
				result = kontroller.getSøketreff(req.getParameter("ar"), req.getParameter("vt"), req.getParameter("s"));
			} else {
				result = kontroller.getRapport("/" + path);
				if ("true".equals(req.getParameter("latin1")) && result != null){ //Default er UTF-8
                    tegnsett = StandardCharsets.ISO_8859_1;
                    result = new String(result.getBytes(tegnsett), tegnsett);
                }
			}

			if (result == null) {
				res.sendError(HttpServletResponse.SC_NOT_FOUND);
				httpLog(req, reqPath, HttpServletResponse.SC_NOT_FOUND, 0, null);
			} else {
				res.setContentType("application/hal+json");
				res.setDateHeader("Expires", 0);
				res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
				res.setHeader("Pragma", "no-cache");
				res.setHeader("Access-Control-Allow-Origin", "*");
				res.setCharacterEncoding(tegnsett.name().toLowerCase());
				res.setStatus(kontroller.erSperrefrist(path) ? HTTP_RETUR_269 : HttpServletResponse.SC_OK);
				res.getWriter().print(result);
				httpLog(req, reqPath, kontroller.erSperrefrist(path) ? HTTP_RETUR_269 : HttpServletResponse.SC_OK, result.length(), null);
			}
		} catch (Exception e) {
			res.sendError(HttpServletResponse.SC_NOT_FOUND);
			httpLog(req, reqPath, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 0, e);
		}
	}

	private void httpLog(HttpServletRequest req, String path, int status, int size, Exception e) {
		String remote = req.getRemoteAddr();
		String xff = req.getHeader("X-Forwarded-For");
		if (xff == null || xff.equals(remote)) {
			xff = "-";
		}
		LOG.info(remote + " " + xff + " \"" + path + "\" " + status + " " + size + (e == null ? "" : "(" + e.getMessage() + ")"));
	}

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

}

