package com.questdiagnostics.applications.resultview.servlet;

import java.io.*;

import javax.servlet.*;
import javax.servlet.http.*;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import org.apache.fop.apps.Driver;
import org.apache.fop.apps.Version;

import com.questdiagnostics.applications.resultview.datanavigation.SessionReportData;

public class ReportGeneratorServlet extends HttpServlet {
 
  java.util.Properties reportProps;
  org.apache.xalan.serialize.Serializer serializer;
  String foOutputFilename, xmlOutputFilename;
  
  public void init() {
    foOutputFilename    = "ReportOutput.fo";
    xmlOutputFilename   = "ReportOutput.xml";

    reportProps = new java.util.Properties();
    reportProps.setProperty("report1001", "lr");
    reportProps.setProperty("report1007", "lr");
    reportProps.setProperty("report1006", "fr");
    reportProps.setProperty("report1009", "ss");
    reportProps.setProperty("report1011", "pvh");
    reportProps.setProperty("report1012", "ps");
    reportProps.setProperty("report1014", "na");

    serializer = org.apache.xalan.serialize.SerializerFactory.getSerializer(
                  org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties("xml"));
  }
  
  public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException {

    String contentType="";
    String size="small";

    HttpSession session = request.getSession();
    
    System.out.println("servlet: session ID = " + session.getId()); 
    System.out.println("ReportGeneratorServlet says hi" + new java.util.Date().toString());

    try {
          
      if ( session.getAttribute("sessionReportObject") != null ) {
 
        String port = "" + request.getServerPort();
       
        SessionReportData srd = (SessionReportData)session.getAttribute("sessionReportObject");
        
        System.out.println("srd.contentType = "   + srd.contentType); 
        System.out.println("srd.reportId = "      + srd.reportId); 
				System.out.println("reportProps.getProperty(report" + srd.reportId + ") = " + reportProps.getProperty("report" + srd.reportId));

        if   ( srd.contentType.equals("pdf") ) {
          contentType = "Fo";    
        }
        else {
          contentType = "Html";    
        }
        renderReport(reportProps.getProperty("report" + srd.reportId), contentType, size, port, srd.reportDom, response);
      }

      else {
        PrintWriter out = response.getWriter();
        out.println("<html><head><title>Error</title></head>\n"+
                    "<body><h1>ReportGeneratorServlet Error 3</h1><h3>No 'fo' "+
                    "request param given.</body></html>");
      }
    } 
    catch (ServletException ex) { throw ex; }
    catch (Exception ex) { throw new ServletException(ex); }
  }

  void renderReport(String reportName, String contentType, String tempDemoSize, String port, 
                    org.w3c.dom.Document xmlDoc, HttpServletResponse response) throws ServletException {
    try {

      String xsltFilename  = getServletConfig().getServletContext().getAttribute("XSLTPathPrefix")	
                         + reportName + "_XmlTo" + contentType + ".xsl";
      File xsltFile = new File(xsltFilename);

/*
        System.out.println("f.getAbsolutePath()  = " + f.getAbsolutePath()  );
        System.out.println("f.getCanonicalPath() = " + f.getCanonicalPath() );
        System.out.println("f.getName()          = " + f.getName()          );
        System.out.println("f.getParent()        = " + f.getParent()        );
        System.out.println("f.getPath()          = " + f.getPath()          );
        System.out.println("f.toString()         = " + f.toString()         );
*/

// output XML for debugging
/*
      File f = new File(xmlOutputFilename);
      FileOutputStream fos = new FileOutputStream(f);
      System.out.println("Writing XML source to: " + f.getAbsolutePath() + "\n");
      serializer.setOutputStream(fos);
      serializer.asDOMSerializer().serialize(xmlDoc);
      fos.close();
*/
      javax.xml.parsers.DocumentBuilderFactory dFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
      dFactory.setNamespaceAware(true);
      javax.xml.parsers.DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
  
      javax.xml.transform.dom.DOMSource xmlDomSource = new javax.xml.transform.dom.DOMSource(xmlDoc);
  
      org.w3c.dom.Document xslDoc = dBuilder.parse(xsltFile);
      javax.xml.transform.dom.DOMSource xslDomSource = new javax.xml.transform.dom.DOMSource(xslDoc);
  
      javax.xml.transform.TransformerFactory tFactory = javax.xml.transform.TransformerFactory.newInstance();
      javax.xml.transform.Templates templates = tFactory.newTemplates(xslDomSource);
      javax.xml.transform.Transformer transformer = templates.newTransformer();
  
      if ( contentType.equals("Fo") ) { 
        if (reportName.equals("lr")) { 
                System.out.println("reportName="+reportName);
                renderPdf(xmlDomSource, transformer, response, 1); }
        else { renderPdf(xmlDomSource, transformer, response, 0); }
      }
      else { 
        renderHtml(xmlDomSource, transformer, response);
      }
    } 
     catch (Exception ex) { throw new ServletException(ex); }
  }
  
  void renderHtml(javax.xml.transform.dom.DOMSource xml, javax.xml.transform.Transformer transformer,
                       HttpServletResponse response) throws ServletException {
    try {
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();

      javax.xml.transform.stream.StreamResult streamResult = new javax.xml.transform.stream.StreamResult(out);
      transformer.transform(xml, streamResult);
    } 
    catch (Exception ex) { throw new ServletException(ex); }

  }

  void renderPdf(javax.xml.transform.dom.DOMSource xml, javax.xml.transform.Transformer transformer,
                       HttpServletResponse response, int isLabReport) throws ServletException {
    try {
      javax.xml.transform.dom.DOMResult foDomResult = new javax.xml.transform.dom.DOMResult();
      transformer.transform(xml, foDomResult);

      org.w3c.dom.Document foDoc = (org.w3c.dom.Document)foDomResult.getNode();

// output FO for debugging
/*
      File f = new File(foOutputFilename);
      FileOutputStream fos = new FileOutputStream(f);
      System.out.println("Writing FO source to: " + f.getAbsolutePath() + "\n");
      serializer.setOutputStream(fos);
      serializer.asDOMSerializer().serialize(foDoc);
      fos.close();
*/

      ByteArrayOutputStream out = new ByteArrayOutputStream();

      org.apache.fop.apps.Driver driver = new org.apache.fop.apps.Driver();
      driver.setErrorDump(true);
      driver.setRenderer(driver.RENDER_PDF);
      driver.setupDefaultMappings() ;
	    driver.setOutputStream(out);
      driver.render(foDoc);

      response.setContentType("application/pdf");

      if (isLabReport==1) { 
        System.out.println("isLabReport=true");
        response.setHeader("Cache-Control", "max-age=20");
//        response.setHeader("Pragma", "no-cache"); 
      }
//      response.setHeader("Cache-Control", "no-cache");
//      response.setHeader("Cache-Control", "max-age=20");
      
      byte[] content = out.toByteArray();
      response.setContentLength(content.length);
      response.getOutputStream().write(content);
      response.getOutputStream().flush();

    } 
    catch (Exception ex) { throw new ServletException(ex); }
  }
}

