package com.capgemini.reports.formatting.statsgen;

import org.apache.commons.io.IOUtils;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.text.ParseException;

/**
 * This class allows sub-classes to generate a String file content, then sends it to the user as a file to be saved on disc.
 */
public abstract class AbstractTableGenerator extends HttpServlet {
  private static Logger LOGGER = LoggerFactory.getLogger(AbstractTableGenerator.class);
  private static final long serialVersionUID = 371492060120193835L;

  @Override
  protected void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws IOException {
    doPost(aRequest, aResponse);
  }

  @Override
  protected void doPost(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws IOException {
    String fileContent;
    String startPeriod = aRequest.getParameter("startPeriod");
    String endPeriod = aRequest.getParameter("endPeriod");
    try {
      fileContent = generateTableAsCSV( startPeriod, endPeriod);
      downloadStringAsCsvFile(aResponse, fileContent);
    }
    catch (ParseException e) {
      LOGGER.error("Parsing error:", e);
    }
  }

  abstract String generateTableAsCSV(final String startPeriod, final String endPeriod) throws ParseException;

  /**
   * Takes a String a puts it into a Stream sent to the (provided) HttpResponse for download, chunk by chunk.
   *
   * @param aResponse    HttpServletResponse which will send the data stream back to the user
   * @param aFileContent the file contents
   * @throws IOException when the download failed
   */
  private void downloadStringAsCsvFile(final HttpServletResponse aResponse, final String aFileContent) throws IOException {
    byte[] byteContents = aFileContent.getBytes();
    int theFileSize = byteContents.length;
    try (ServletOutputStream theServletOutput = aResponse.getOutputStream()) {
      aResponse.setContentType("application/download");
      aResponse.setHeader("Content-Disposition", "attachment;filename=\"" + getFilename() + ".csv\"");

      aResponse.setContentLength(theFileSize);
      Reader input = new StringReader(aFileContent);
      IOUtils.copy(input, theServletOutput);
      theServletOutput.flush();
    }
  }

  protected abstract String getFilename();
}
