// Path: common/dataobjects/src/main/java/com/sastix/cms/common/dataobjects/htmltopdf/Param.java
// @Getter @Setter @AllArgsConstructor @ToString
// public class Param {
// 
//     String key;
//     
//     String value;
// 
// }
// 
// Path: common/services/src/test/com/sastix/cms/common/services/htmltopdf/config/HtmlToPdfConfiguration.java
// @Configuration
// @ComponentScan({"com.sastix.cms.common.services.htmltopdf.config"})
// public class HtmlToPdfConfiguration {
//     @Value("/data/common/wkhtmltopdf/wkhtmltopdf")
//     private String wkhtmltopdf;
// 
//     @Bean
//     HtmlToPdfConfig htmlToPdfConfig(){
//         return new HtmlToPdfConfig(wkhtmltopdf);
//     }
// }
// 
// Path: common/services/src/main/java/com/sastix/cms/common/services/htmltopdf/config/HtmlToPdfConfig.java
// @Slf4j
// @Getter @Setter @AllArgsConstructor @NoArgsConstructor
// public class HtmlToPdfConfig {
// 
//     private String wkhtmltopdfCommand;
// 
//     /**
//      * Attempts to find the `wkhtmltopdf` executable in the system path.
//      *
//      * @return
//      */
//     public String findExecutable() {
//         String ret = null;
//         try {
//             String osname = System.getProperty("os.name").toLowerCase();
// 
//             String cmd;
//             if (osname.contains("windows"))
//                 cmd = "where wkhtmltopdf";
//             else cmd = "which wkhtmltopdf";
// 
//             Process p = Runtime.getRuntime().exec(cmd);
//             p.waitFor();
// 
//             BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
// 
//             StringBuilder sb = new StringBuilder();
//             String line = "";
//             while ((line = reader.readLine()) != null) {
//                 sb.append(line);
//             }
// 
//             if (sb.toString().isEmpty())
//                 throw new RuntimeException();
// 
//             ret = sb.toString();
//         } catch (InterruptedException e) {
//             log.error("InterruptedException while trying to find wkhtmltopdf executable",e);
//         } catch (IOException e) {
//             log.error("IOException while trying to find wkhtmltopdf executable", e);
//         } catch (RuntimeException e) {
//             log.error("RuntimeException while trying to find wkhtmltopdf executable", e);
//         }
//         return ret;
//     }
// }


import com.sastix.cms.common.dataobjects.htmltopdf.Param;
import com.sastix.cms.common.dataobjects.htmltopdf.page.PageType;
import com.sastix.cms.common.services.htmltopdf.config.HtmlToPdfConfiguration;
import com.sastix.cms.common.services.htmltopdf.config.HtmlToPdfConfig;
import org.apache.pdfbox.io.RandomAccessBufferedFileInputStream;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.concurrent.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;

        // GIVEN an html template containing special characters that java stores in utf-16 internally
        Pdf pdf = pdfBuilder.build();
        pdf.addPage("<html><head><meta charset=\"utf-8\"></head><h1>Müller</h1></html>", PageType.htmlAsString);

        String tempFolder = temporaryFolder.newFolder().getPath();
        pdf.saveAs(tempFolder+"/output.pdf");

        // WHEN
        byte[] pdfBytes = pdf.getPDF();

        PDFParser parser = new PDFParser(new RandomAccessBufferedFileInputStream(new ByteArrayInputStream(pdfBytes)));

        // that is a valid PDF (otherwise an IOException occurs)
        parser.parse();
        PDFTextStripper pdfTextStripper = new PDFTextStripper();
        String pdfText = pdfTextStripper.getText(new PDDocument(parser.getDocument()));

        assertThat("document should contain the creditorName", pdfText, containsString("Müller"));
    }

    final int numberOfTasks = 1500;
    CountDownLatch latch = new CountDownLatch(numberOfTasks);
    ConcurrentMap<Integer,Long> cmap = new ConcurrentHashMap<>();

    @Test
    public void performanceTest() throws InterruptedException {
        int NTHREDS = 30;//the lesser the threads, the completion time increases. At least 15 threads for better performance on my laptop
        ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
        long start = DateTime.now().getMillis();
// Path: common/dataobjects/src/main/java/com/sastix/cms/common/dataobjects/htmltopdf/Param.java
// @Getter @Setter @AllArgsConstructor @ToString
// public class Param {
// 
//     String key;
//     
//     String value;
// 
// }
// 
// Path: common/services/src/test/com/sastix/cms/common/services/htmltopdf/config/HtmlToPdfConfiguration.java
// @Configuration
// @ComponentScan({"com.sastix.cms.common.services.htmltopdf.config"})
// public class HtmlToPdfConfiguration {
//     @Value("/data/common/wkhtmltopdf/wkhtmltopdf")
//     private String wkhtmltopdf;
// 
//     @Bean
//     HtmlToPdfConfig htmlToPdfConfig(){
//         return new HtmlToPdfConfig(wkhtmltopdf);
//     }
// }
// 
// Path: common/services/src/main/java/com/sastix/cms/common/services/htmltopdf/config/HtmlToPdfConfig.java
// @Slf4j
// @Getter @Setter @AllArgsConstructor @NoArgsConstructor
// public class HtmlToPdfConfig {
// 
//     private String wkhtmltopdfCommand;
// 
//     /**
//      * Attempts to find the `wkhtmltopdf` executable in the system path.
//      *
//      * @return
//      */
//     public String findExecutable() {
//         String ret = null;
//         try {
//             String osname = System.getProperty("os.name").toLowerCase();
// 
//             String cmd;
//             if (osname.contains("windows"))
//                 cmd = "where wkhtmltopdf";
//             else cmd = "which wkhtmltopdf";
// 
//             Process p = Runtime.getRuntime().exec(cmd);
//             p.waitFor();
// 
//             BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
// 
//             StringBuilder sb = new StringBuilder();
//             String line = "";
//             while ((line = reader.readLine()) != null) {
//                 sb.append(line);
//             }
// 
//             if (sb.toString().isEmpty())
//                 throw new RuntimeException();
// 
//             ret = sb.toString();
//         } catch (InterruptedException e) {
//             log.error("InterruptedException while trying to find wkhtmltopdf executable",e);
//         } catch (IOException e) {
//             log.error("IOException while trying to find wkhtmltopdf executable", e);
//         } catch (RuntimeException e) {
//             log.error("RuntimeException while trying to find wkhtmltopdf executable", e);
//         }
//         return ret;
//     }
// }


// Path: common/services/src/test/com/sastix/cms/common/services/htmltopdf/PdfTest.java
import com.sastix.cms.common.dataobjects.htmltopdf.Param;
import com.sastix.cms.common.dataobjects.htmltopdf.page.PageType;
import com.sastix.cms.common.services.htmltopdf.config.HtmlToPdfConfiguration;
import com.sastix.cms.common.services.htmltopdf.config.HtmlToPdfConfig;
import org.apache.pdfbox.io.RandomAccessBufferedFileInputStream;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.concurrent.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;


        // GIVEN an html template containing special characters that java stores in utf-16 internally
        Pdf pdf = pdfBuilder.build();
        pdf.addPage("<html><head><meta charset=\"utf-8\"></head><h1>Müller</h1></html>", PageType.htmlAsString);

        String tempFolder = temporaryFolder.newFolder().getPath();
        pdf.saveAs(tempFolder+"/output.pdf");

        // WHEN
        byte[] pdfBytes = pdf.getPDF();

        PDFParser parser = new PDFParser(new RandomAccessBufferedFileInputStream(new ByteArrayInputStream(pdfBytes)));

        // that is a valid PDF (otherwise an IOException occurs)
        parser.parse();
        PDFTextStripper pdfTextStripper = new PDFTextStripper();
        String pdfText = pdfTextStripper.getText(new PDDocument(parser.getDocument()));

        assertThat("document should contain the creditorName", pdfText, containsString("Müller"));
    }

    final int numberOfTasks = 1500;
    CountDownLatch latch = new CountDownLatch(numberOfTasks);
    ConcurrentMap<Integer,Long> cmap = new ConcurrentHashMap<>();

    @Test
    public void performanceTest() throws InterruptedException {
        int NTHREDS = 30;//the lesser the threads, the completion time increases. At least 15 threads for better performance on my laptop
        ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
        long start = DateTime.now().getMillis();
        for (int i = 0; i < numberOfTasks; i++) {