package systems.sdw;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Properties;
import java.util.UUID;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;

import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
import org.mustangproject.BankDetails;
import org.mustangproject.Contact;
import org.mustangproject.Invoice;
import org.mustangproject.Item;
import org.mustangproject.Product;
import org.mustangproject.TradeParty;
import org.mustangproject.ZUGFeRD.PDFAConformanceLevel;
import org.mustangproject.ZUGFeRD.ZUGFeRDExporterFromA3;
import org.mustangproject.ZUGFeRD.ZUGFeRDImporter;

import systems.sdw.basetech.json.JSONArray;
import systems.sdw.basetech.json.JSONException;
import systems.sdw.basetech.json.JSONObject;

// @WebServlet("/fc")
@MultipartConfig (
		//location= "/Users/benediktwismans/tmp",
		location= "/tmp",
		fileSizeThreshold = 1024,
		maxFileSize = 1024*1024*10,
		maxRequestSize = 1024*1024
		)

public class Frontcontroller extends HttpServlet {

	private static final long serialVersionUID = 1L;

	private static final String encodingUTF8="UTF-8";	
	private static final String tmpDir="tmpdir";	
	private static final String dmsDir="dmsdir";	
	private static final String debug="debug";	

	private static Properties propsSystem = new Properties();



	public void init(ServletConfig servletconfig) throws ServletException {
		System.out.println("ZFD SDW Frontcontroller ->INIT");
		//
		super.init(servletconfig);
		//
		ServletContext context=getServletContext();
		propsSystem.setProperty(tmpDir, context.getInitParameter("system.defaults.tmpPath"));
		propsSystem.setProperty(dmsDir, context.getInitParameter("system.defaults.dmsPath"));
		propsSystem.setProperty(debug, context.getInitParameter("system.debug"));
		propsSystem.list(System.out);
		//
		System.out.println("ZFD SDW Frontcontroller <-INIT");
	}

	@SuppressWarnings("unused")
	private void debugInfo(HttpServletRequest request) throws IOException, ServletException {
		//
		String contenttyp = request.getContentType();
		System.out.println("CONTENTTYPE "+contenttyp);

		Collection<Part> parts=request.getParts();
		Iterator<Part> it=parts.iterator();

		while (it.hasNext()) {
			Part part=it.next();
			System.out.println("");
			System.out.println("NAME " + part.getName());
			System.out.println("SIZE " + part.getSize());
			System.out.println("FILE " + part.getSubmittedFileName());
			System.out.println("TYPE " + part.getContentType());
		}
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("ZFD SDW doPost ->INIT");
		//
		HttpSession session=request.getSession(true);
		String sessionid=session.getId().toString();
		//
		try {
			request.setCharacterEncoding(encodingUTF8);
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}

		if ("true"==propsSystem.getProperty(debug, "false")) debugInfo(request);

		//	PDF
		File pdf=processPDF(request, sessionid);

		// JSON
		JSONObject json=processJSON(request);

		File targetFile=ZugferdUtil.createZugferdPDF(pdf, json);
		
		// Response
		if (targetFile!=null) {
			processResponse(response, targetFile, targetFile.getName());
		} else {
			processResponse(response, pdf, pdf.getName());
		}
		//
		System.out.println("ZFD SDW doPost <-INIT");
	}    

	
	private static JSONObject processJSON(HttpServletRequest request) throws IOException, ServletException  {

		Part jsonPart=request.getPart("rechnung_json");

		ByteArrayOutputStream out=new ByteArrayOutputStream();
		InputStream in=jsonPart.getInputStream();

		byte[] buffer = new byte[1024];
		for (int length; (length = in.read(buffer)) != -1; ) out.write(buffer, 0, length);

		try {
			return new JSONObject(out.toString(encodingUTF8));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return null;
	}


	private static File processPDF(HttpServletRequest request, String sessionid) throws IOException, ServletException {

		Part pdfPart=request.getPart("rechnung_pdf");
		
		try {
			//File file=new File("/Users/benediktwismans/tmp", sessionid+"_"+pdfPart.getSubmittedFileName());
			File file=new File("/tmp/"+UUID.randomUUID());
			FileOutputStream out=new FileOutputStream(file);
			InputStream in = pdfPart.getInputStream();
			byte[] buf = new byte[1024]; int nread = 0, total_read = 0;

			while (-1 != (nread = in.read(buf))) {
				total_read += nread;
				out.write(buf, 0, nread);
			}
			out.close();
			in.close();
			System.out.println("\n"+getLogPrefix(sessionid)+" ZFD fc "+pdfPart.getName()+" to "+file.getAbsolutePath() + " BYTES: " + total_read);
			return file;

		} 
		catch (FileNotFoundException e) {
			e.printStackTrace();
		} 
		catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}


	private static void processResponse (HttpServletResponse response, java.io.File file, String filename) throws IOException  {
		//
		response.setHeader("Cache-Control", "no-cache");	//	HTTP 1.1
		response.setHeader("Pragma", "no-cache");	//	HTTP 1.0
		response.setDateHeader("Expires", 0);	//	Kein Proxy-Caching
		response.setCharacterEncoding(encodingUTF8);
		response.setContentType("application/pdf");

		//
		//	Das Dokument in den Servletresponse schreiben
		//
		if (file==null) System.out.print(" error: file is null ");
		else if (!file.exists()) System.out.print(" error: "+file.getCanonicalPath()+" not found");
		else {
			int bytes=Long.valueOf(file.length()).intValue();
			java.io.FileInputStream in=new java.io.FileInputStream(file);

			byte[] content=new byte[bytes]; 
			bytes=in.read(content);
			response.setContentLength(content.length);		
			System.out.println("SDW Download: Bytes:" +bytes);

			//response.setHeader("Content-disposition", "inline; filename=\""+filename+"\"");
			response.setHeader("Content-disposition", "attachment; filename=\""+filename+"\"");

			response.getOutputStream().write(content);
			response.getOutputStream().flush();
			response.getOutputStream().close();

			in.close();
		}
	}

	private static String getLogPrefix(String sessionid) {
		return 	new java.text.SimpleDateFormat("dd.MM.yyyy HH:mm:ss ").format(new java.util.Date())+Frontcontroller.class.getCanonicalName()+" "+sessionid+" ";
	}

	public void destroy() {
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
		processGetRequest(request, response);
	}

	private void processGetRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException  {
		throw new ServletException("GET-Request wird von SDW ZFD fc nicht behandelt");
	}

}











