package com.capgemini.reports;

import com.capgemini.reports.formatting.ErrorPageTemplate;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** Forwards the request to the report's own jsp. */
@Slf4j
@WebServlet("/dispatcherServlet")
public class DispatcherServlet extends HttpServlet {

    private static final long serialVersionUID = 490514018643346053L;

    /**
     * URL pattern. <br>
     * There are 3 matching possibilities:
     * <ol>
     * <li>"REPORT_R" followed by an optional "B" for RB01 reports followed by a two-digit number "XX"</li>
     * <li>An optional series of all-alpha words preceded by whitespace like "_Document_Revision"</li>
     * <li>"&" separator then anything that isn't a whitespace, then the end of the string</li>
     * </ol>
     * 
     * So these work:
     * <ul>
     * <li>REPORT_R01</li>
     * <li>REPORT_R20</li>
     * <li>REPORT_R19</li>
     * <li>REPORT_R15_A</li>
     * <li>REPORT_R15_B</li>
     * <li>REPORT_R19_Document_Revision</li>
     * <li>REPORT_R19_Document</li>
     * <li>REPORT_R19_Document_Revision</li>
     * <li>REPORT_R19&truc=machin</li>
     * <li>REPORT_RB05</li>
     * <li>REPORT_RB01</li>
     * </ul>
     * And these don't:
     * <ul>
     * <li>REPORT_R011</li>
     * <li>RAPORT_R01</li>
     * <li>REPORT_RB1</li>
     * <li>REPORT_RB6</li>
     * <li>REPORT_R15A</li>
     * <li>REPORT_R19_Document-Revision</li>
     * </ul>
     */
    private static final String URL_PATTERN = "(REPORT_RB?[0-9][0-9])(_[A-Za-z]+)*(&[\\S]*)?$";

    /**
     * Forwards the request to the appropriate web page.
     * 
     * @param aRequest The user request
     * @param aResponse The expected response
     * @throws ServletException
     * @throws IOException
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    @Override
    protected void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws ServletException, IOException {
        ServletContext context = getServletContext();

        String theUrl = aRequest.getQueryString();
        Pattern pattern = Pattern.compile(URL_PATTERN);
        Matcher matcher = pattern.matcher(theUrl);
        if (matcher.find()) {
            final String reportId = matcher.group(1); // Group 0 is the whole string, group 1 is REPORT_RXX
            String target = "/index.jsp?rd_id=" + reportId.toLowerCase(Locale.FRENCH);
            RequestDispatcher dispatcher = context.getRequestDispatcher(target);
            // Will go to each report's report_rXX.html
            dispatcher.forward(aRequest, aResponse);
        }
        else {
            String theErrorTitle = "Unable to download file";
            String theErroMessage = "Could not extract target report of the form \"" + URL_PATTERN + "\" in request URL parameters";
            log.error(theErrorTitle + ": " + theErroMessage + " = " + theUrl);
            ErrorPageTemplate theErrorTemplate = new ErrorPageTemplate(theErrorTitle, theErroMessage);
            aResponse.getWriter().write(theErrorTemplate.generateCode());
        }
    }
}
