/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Document;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.xpath.XPathAPI;
import org.apache.xpath.objects.XObject;

import org.apache.xmlgraphics.io.Resource;
import org.apache.xmlgraphics.io.ResourceResolver;

import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.FopFactoryBuilder;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.render.xml.XMLRenderer;

import static org.apache.fop.FOPTestUtils.getBaseDir;

/**
 * Tests URI resolution facilities.
 */
public class URIResolutionTestCase {

    private SAXTransformerFactory tfactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();

    private static final File BACKUP_DIR = new File(getBaseDir(), "build/test-results");

    private static FopFactory fopFactory;

    @BeforeClass
    public static void makeDirs() {
        BACKUP_DIR.mkdirs();
        fopFactory = new FopFactoryBuilder(new File(".").getAbsoluteFile().toURI(),
                new CustomURIResolver()).build();
    }

    private static File getTestDir() {
        return new File(getBaseDir(), "test/xml/uri-testing/");
    }

    @Test
    public void innerTestFO1() throws Exception {
        File foFile = new File(getTestDir(), "custom-scheme/only-scheme-specific-part.fo");

        FOUserAgent ua = fopFactory.newFOUserAgent();

        Document doc = createAreaTree(foFile, ua);

        // XPath checking on the area tree
        assertEquals("viewport for external-graphic is missing",
                "true", evalXPath(doc, "boolean(//flow/block[1]/lineArea/viewport)"));
        assertEquals("46080", evalXPath(doc, "//flow/block[1]/lineArea/viewport/@ipd"));
        assertEquals("46080", evalXPath(doc, "//flow/block[1]/lineArea/viewport/@bpd"));
    }

    /**
     * Test custom URI resolution with a hand-written URIResolver.
     * @throws Exception if anything fails
     */
    @Test
    public void testFO2() throws Exception {
        File foFile = new File(getTestDir(), "custom-scheme/only-scheme-specific-part-svg.fo");

        FOUserAgent ua = fopFactory.newFOUserAgent();

        ByteArrayOutputStream baout = new ByteArrayOutputStream();

        Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, ua, baout);

        Transformer transformer = tfactory.newTransformer(); //Identity transf.
        Source src = new StreamSource(foFile);
        Result res = new SAXResult(fop.getDefaultHandler());
        transformer.transform(src, res);

        OutputStream out = new java.io.FileOutputStream(
                new File(BACKUP_DIR, foFile.getName() + ".pdf"));
        try {
            baout.writeTo(out);
        } finally {
            IOUtils.closeQuietly(out);
        }

        //Test using PDF as the area tree doesn't invoke Batik so we could check
        //if the resolver is actually passed to Batik by FOP
        assertTrue("Generated PDF has zero length", baout.size() > 0);
    }

    private Document createAreaTree(File fo, FOUserAgent ua)
            throws TransformerException, FOPException {
        DOMResult domres = new DOMResult();
        //Setup Transformer to convert the area tree to a DOM
        TransformerHandler athandler = tfactory.newTransformerHandler();
        athandler.setResult(domres);

        XMLRenderer atrenderer = new XMLRenderer(ua);
        atrenderer.setContentHandler(athandler);
        ua.setRendererOverride(atrenderer);

        Fop fop = fopFactory.newFop(ua);

        Transformer transformer = tfactory.newTransformer(); //Identity transf.
        Source src = new StreamSource(fo);
        Result res = new SAXResult(fop.getDefaultHandler());
        transformer.transform(src, res);

        Document doc = (Document) domres.getNode();
        saveAreaTreeXML(doc, new File(BACKUP_DIR, fo.getName() + ".at.xml"));
        return doc;
    }

    private String evalXPath(Document doc, String xpath) {
        XObject res;
        try {
            res = XPathAPI.eval(doc, xpath);
        } catch (TransformerException e) {
            throw new RuntimeException("XPath evaluation failed: " + e.getMessage());
        }
        return res.str();
    }

    /**
     * Save the area tree XML for later inspection.
     * @param doc area tree as a DOM document
     * @param target target file
     * @throws TransformerException if a problem occurs during serialization
     */
    protected void saveAreaTreeXML(Document doc, File target) throws TransformerException {
        Transformer transformer = tfactory.newTransformer();
        Source src = new DOMSource(doc);
        Result res = new StreamResult(target);
        transformer.transform(src, res);
    }

    private static final class CustomURIResolver implements ResourceResolver {
        private final ResourceResolver defaultImpl =  ResourceResolverFactory.createDefaultResourceResolver();

        public Resource getResource(URI uri) throws IOException {
            if (uri.getScheme().equals("funky") && uri.getSchemeSpecificPart().equals("myimage123")) {
                return new Resource("", new FileInputStream("test/resources/images/bgimg300dpi.jpg"));
            }

            return defaultImpl.getResource(uri);
        }

        public OutputStream getOutputStream(URI uri) throws IOException {
            return defaultImpl.getOutputStream(uri);
        }

    }
}
