/*
 * 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.render.pdf.pdfbox;

import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;

import org.apache.xmlgraphics.image.loader.util.ImageUtil;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFPage;
import org.apache.fop.pdf.PDFResources;
import org.apache.fop.pdf.Version;
import org.apache.fop.render.pdf.pdfbox.Cache.ValueMaker;

/**
 * Abstract base class for implementation of FOP's image handler interfaces (old and new)
 * which can use PDFBox to parse an existing PDF file and write that to the
 * target PDF as a Form XObject.
 */
public abstract class AbstractPDFBoxHandler {

    private static final Cache.Type CACHE_TYPE = Cache.Type.valueOf(
            System.getProperty("fop.pdfbox.doc-cache", Cache.Type.WEAK.name()).toUpperCase());

    private static Cache<String, Map<Object, Object>> createDocumentCache() {
        return Cache.createCache(CACHE_TYPE);
    }

    private static final ValueMaker<Map<Object, Object>> MAP_MAKER = new ValueMaker<Map<Object, Object>>() {
        public Map<Object, Object> make() throws Exception {
            return new HashMap<Object, Object>();
        }
    };

    private static Map<Object, Cache<String, Map<Object, Object>>> objectCacheMap
        = Collections.synchronizedMap(new WeakHashMap<Object, Cache<String, Map<Object, Object>>>());

    protected String createStreamForPDF(ImagePDF image, PDFPage targetPage, FOUserAgent userAgent,
            AffineTransform at, FontInfo fontinfo, Rectangle pos) throws IOException {

        EventBroadcaster eventBroadcaster = userAgent.getEventBroadcaster();
        String originalImageUri = image.getInfo().getOriginalURI();
        final int selectedPage = ImageUtil.needPageIndexFromURI(originalImageUri);

        PDDocument pddoc = image.getPDDocument();
        float pdfVersion = pddoc.getDocument().getVersion();
        Version inputDocVersion = Version.getValueOf(String.valueOf(pdfVersion));
        PDFDocument pdfDoc = targetPage.getDocument();

        if (pdfDoc.getPDFVersion().compareTo(inputDocVersion) < 0) {
            try {
                pdfDoc.setPDFVersion(inputDocVersion);
            } catch (IllegalStateException e) {
                getEventProducer(eventBroadcaster).pdfVersionMismatch(this,
                         pdfDoc.getPDFVersionString(), String.valueOf(pdfVersion));
            }
        }

        //Encryption test
        if (pddoc.isEncrypted()) {
            getEventProducer(eventBroadcaster).encryptedPdf(this);
            return null;
        }


        //Warn about potential problems with PDF/A and PDF/X
        if (pdfDoc.getProfile().isPDFAActive()) {
            getEventProducer(eventBroadcaster).pdfAActive(this);
        }
        if (pdfDoc.getProfile().isPDFXActive()) {
            getEventProducer(eventBroadcaster).pdfXActive(this);
        }

        Map<Object, Object> objectCache = getObjectCache(originalImageUri, userAgent);

        PDPage page = (PDPage) pddoc.getDocumentCatalog().getAllPages().get(selectedPage);

        if (targetPage.getPDFResources().getParentResources() == null) {
            PDFResources res = pdfDoc.getFactory().makeResources();
            res.setParentResources(pdfDoc.getResources());
            targetPage.put("Resources", res);
        }

        PDFBoxAdapter adapter = new PDFBoxAdapter(targetPage, objectCache);
        String stream = adapter.createStreamFromPDFBoxPage(pddoc, page, originalImageUri,
                eventBroadcaster, at, fontinfo, pos);
        return stream;
    }

    private Map<Object, Object> getObjectCache(String originalImageUri,
            Object documentScopedReference) {
        String fileUri = getImagePath(originalImageUri);
        try {
            return getDocumentCache(documentScopedReference)
                        .getValue(fileUri, MAP_MAKER);
        } catch (Exception e) {
            // We cannot recover from this
            throw new RuntimeException(e);
        }
    }

    private Cache<String, Map<Object, Object>> getDocumentCache(Object documentScopedReference) {
        Cache<String, Map<Object, Object>> documentCache = objectCacheMap.get(documentScopedReference);
        if (documentCache == null) {
            documentCache = createDocumentCache();
            objectCacheMap.put(documentScopedReference, documentCache);
        }
        return documentCache;
    }

    private String getImagePath(String originalImageUri) {
        int hashIndex = originalImageUri.indexOf('#');
        if (hashIndex > 0) {
            return originalImageUri.substring(0, hashIndex);
        } else {
            return originalImageUri;
        }
    }

    private PDFBoxEventProducer getEventProducer(EventBroadcaster eventBroadcaster) {
        return PDFBoxEventProducer.Provider.get(eventBroadcaster);
    }
}
