/*
 * This file (SolveJasperBugTest.java) is part of DebGen-ReportPrintLib  developed by ASTRID Research.
 * All rights reserved. Reproduction, modification, use or disclosure
 * to third parties without express authority is forbidden.
 *
 *  Copyright ASTRID Research, Hungary, 2010.
 *
 *  ASTRID Research
 *  Headquaters: Csapó utca 42. Debrecen H-4029 HUNGARY
 *  Phone: +36-52-533-173        Fax: +36-52-533-174
 *  Web: http://www.astrid.hu    E-mail: info@astrid.hu
 *
 * Project name: DEBGEN-Biobank-Project.
 * File last modified at 2010.01.10 11:43
 */
package hu.astrid.printxml;

import hu.astrid.printxml.generator.PdfGeneratorFromDocument;
import hu.astrid.printxml.generator.PdfGeneratorFromURI;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map.Entry;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import static org.junit.Assert.*;

/**
 * Tests to fail when the JasperBug problem is solved
 * UPDATE: The bug is solved, the test should not fail anymore...
 * @author inagy
 */
public class SolveJasperBugTest {

    private static HashMap<File, Boolean> files = new HashMap<File, Boolean>();

    @BeforeClass
    public static void setUpClass() throws Exception {
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/namedpatientexample.xml"), true);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/unnamedpatientexample.xml"), true);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/namedpatient_invalid.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/unnamedpatient_invalid.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/namedpatient_invalid_1.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/unnamedpatient_invalid_1.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/namedpatient_invalid_2.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/unnamedpatient_invalid_2.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/namedpatient_invalid_3.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/unnamedpatient_invalid_3.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/namedpatient_invalid_4.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/unnamedpatient_invalid_4.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/namedpatient_not_wellformed.xml"), false);
        files.put(new File("DebGen-ReportPrintLib/src/test/resources/unnamedpatient_not_wellformed.xml"), false);
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    @Test
    public void testGetAsStream() throws Exception {
        System.out.println("getAsStream");
        for (Entry<File, Boolean> entry : files.entrySet()) {
            try {
                System.out.println("Testing file: " + entry.getKey().getAbsolutePath());
                System.out.println("Expected value: " + entry.getValue());

                PdfGeneratorFromURI instance = new PdfGeneratorFromURI(new Locale("hu"));
                instance.setResourceName("/CommonAnalysisRequest-");
                InputStream result = instance.getAsStream(entry.getKey().toURI());
//                if (entry.getValue()) {
//                    assertTrue("HU: No validation. OK - " + result.available() + "bytes available.", result.available() > 3000);
//                } else {
//                    assertFalse("HU: No validation. Fail - " + entry.getKey().getAbsolutePath(), result != null && result.available() > 3000);
//                }
//                PdfGeneratorFromURI instance2 = new PdfGeneratorFromURI(Locale.ENGLISH);
//                InputStream result2 = instance2.getAsStream(entry.getKey().toURI());
//                if (entry.getValue()) {
//                    assertTrue("EN: No validation. OK - " + result2.available() + "bytes available.", result2.available() > 900);
//                } else {
//                    assertFalse("EN: No validation. Fail - " + entry.getKey().getAbsolutePath(), result2 != null && result2.available() > 900);
//                }
                try {
                    Document document = createDocumentBuilder(createDocumentBuilderFactory()).parse(entry.getKey());
                    PdfGeneratorFromDocument failGenerator = new PdfGeneratorFromDocument(new Locale("hu"));
                    failGenerator.setResourceName("/CommonAnalysisRequest-");
                    InputStream failed = failGenerator.getAsStream(document);
                    if (entry.getValue()) {
                        assertTrue(Math.abs(failed.available()-result.available())<100 && failed.available() > 3000);
                    }

                    //InputStream failed2 = new PdfGeneratorFromDocument(Locale.ENGLISH).getAsStream(document);
                    //assertTrue("HU: Validation. Fail - " + failed.available() + "bytes available. (Empty PDF)", failed.available() < 900);
//                    assertTrue("EN: Validation. Fail - " + failed2.available() + "bytes available. (Empty PDF)", failed2.available() < 900);
                } catch (Exception ex) {
                    if (entry.getValue()) {
                        ex.printStackTrace(System.out);
                        fail("No exception allowed, but found: " + ex);
                    } else {
                        assertTrue("Exception is allowed now.", !entry.getValue());
                    }
                }
            } catch (Exception ex) {
                if (entry.getValue()) {
                    fail("No exception allowed, but found: " + ex);
                } else {
                    assertTrue("Exception is allowed now.", !entry.getValue());
                }
            }
        }
    }

    /**
     * Creates a new DocumentBuilder instance with the default error handler
     *
     * @param builderFactory The builder factory, which is used to this process.
     * @return builder
     * @throws ParserConfigurationException When the parser couldn't be configured.
     */
    private DocumentBuilder createDocumentBuilder(DocumentBuilderFactory builderFactory) throws ParserConfigurationException {
        DocumentBuilder builder = builderFactory.newDocumentBuilder();
        builder.setErrorHandler(new ErrorHandler() {

            public void warning(SAXParseException exception) throws SAXException {
                throw exception;
            }

            public void error(SAXParseException exception) throws SAXException {
                throw exception;
            }

            public void fatalError(SAXParseException exception) throws SAXException {
                throw exception;
            }
        });
        return builder;
    }

    /**
     * Creates a new DocumentBuilderFactory with or without the validating feature
     *
     * @return builderFactory
     * @throws IllegalArgumentException Probably never, but I could be wrong, when I set a wrong attribute.
     */
    protected DocumentBuilderFactory createDocumentBuilderFactory() throws IllegalArgumentException {
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        builderFactory.setNamespaceAware(true);
        builderFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
        builderFactory.setValidating(true);
        return builderFactory;
    }
}
