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

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.xml.transform.stream.StreamResult;

import org.junit.Assert;
import org.junit.Test;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.pdf.PDFContentGenerator;
import org.apache.fop.render.pdf.PDFDocumentHandler;
import org.apache.fop.render.pdf.PDFPainter;

public class PDFLinearizationTestCase {
    private int objectLeast;
    private int[] objects;

    @Test
    public void testPDF() throws IOException {
        PDFDocument doc = new PDFDocument("");
        doc.setLinearizationEnabled(true);
        PDFResources resources = new PDFResources(doc);
        PDFResourceContext context = new PDFResourceContext(resources);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PDFContentGenerator gen = null;
        for (int i = 0; i < 2; i++) {
            gen = new PDFContentGenerator(doc, out, context);
            Rectangle2D.Float f = new Rectangle2D.Float();
            PDFPage page = new PDFPage(resources, i, f, f, f, f);
            doc.registerObject(page);
            doc.registerObject(gen.getStream());
            page.setContents(new PDFReference(gen.getStream()));
        }
        gen.flushPDFDoc();
        byte[] data = out.toByteArray();
        checkPDF(data);
    }

    @Test
    public void testImage() throws Exception {
        String fopxconf = "<fop version=\"1.0\"><renderers>"
                + "<renderer mime=\"application/pdf\">"
                + "<linearization>true</linearization>"
                + "</renderer></renderers></fop>";
        FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI(),
                new ByteArrayInputStream(fopxconf.getBytes()));
        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
        IFContext ifContext = new IFContext(foUserAgent);
        PDFDocumentHandler documentHandler = new PDFDocumentHandler(ifContext);
        documentHandler.getConfigurator().configure(documentHandler);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        documentHandler.setFontInfo(new FontInfo());
        documentHandler.setResult(new StreamResult(out));
        documentHandler.startDocument();
        documentHandler.startPage(0, "", "", new Dimension());
        PDFPainter pdfPainter = new PDFPainter(documentHandler, null);
        pdfPainter.drawImage("test/resources/fop/svg/logo.jpg", new Rectangle());
        documentHandler.endPage();
        Assert.assertFalse(out.toString().contains("/Subtype /Image"));
        documentHandler.endDocument();
        Assert.assertTrue(out.toString().contains("/Subtype /Image"));
    }

    private void checkPDF(byte[] data) throws IOException {
        checkHintTable(data);
        InputStream is = new ByteArrayInputStream(data);
        Map<String, StringBuilder> objs = readObjs(is);

        List<String> keys = new ArrayList<String>(objs.keySet());
        int start = keys.indexOf("1 0 obj");
        Assert.assertTrue(start > 1);
        int j = 1;
        for (int i = start; i < keys.size(); i++) {
            Assert.assertEquals(keys.get(i), j + " 0 obj");
            j++;
        }
        for (int i = 0; i < start; i++) {
            Assert.assertEquals(keys.get(i), j + " 0 obj");
            j++;
        }

        checkFirstObj(data);
        checkTrailer(data);

        String firstObj = objs.values().iterator().next().toString().replace("\n", "");
        Assert.assertTrue(firstObj.startsWith("<<  /Linearized 1  /L " + data.length));
        Assert.assertTrue(firstObj.endsWith("startxref0%%EOF"));
        int pageObjNumber = getValue("/O", firstObj);
        Assert.assertTrue(objs.get(pageObjNumber + " 0 obj").toString().contains("/Type /Page"));
        Assert.assertTrue(objs.get("5 0 obj").toString().contains("/Type /Pages"));

        int total = 0;
        for (int i : objects) {
            total += i;
        }
        Assert.assertEquals(total, objs.size() - 6);
    }

    private void checkFirstObj(byte[] data) throws IOException {
        int firstObjPos = getValue("/E", getFirstObj(data));
        InputStream is = new ByteArrayInputStream(data);
        Assert.assertEquals(is.skip(firstObjPos), firstObjPos);
        byte[] obj = new byte[10];
        Assert.assertEquals(is.read(obj), obj.length);
        Assert.assertTrue(new String(obj).startsWith("1 0 obj"));
    }

    private void checkTrailer(byte[] data) throws IOException {
        int trailerPos = getValue("/T", getFirstObj(data));
        InputStream is = new ByteArrayInputStream(data);
        Assert.assertEquals(is.skip(trailerPos), trailerPos);
        byte[] obj = new byte[20];
        Assert.assertEquals(is.read(obj), obj.length);
        Assert.assertTrue(new String(obj).startsWith("0000000000 65535 f"));
    }

    private int getValue(String name, String firstObj) throws IOException {
        String[] split = firstObj.split(" ");
        for (int i = 0; i < split.length; i++) {
            if (split[i].equals(name)) {
                return Integer.valueOf(split[i + 1].replace(">>", ""));
            }
        }
        throw new IOException(name + " not found " + firstObj);
    }

    private int[] getArrayValue(String name, String firstObj) throws IOException {
        String[] split = firstObj.split(" ");
        for (int i = 0; i < split.length; i++) {
            if (split[i].equals(name)) {
                int[] v = new int[2];
                v[0] = Integer.valueOf(split[i + 1].replace("[", ""));
                v[1] = Integer.valueOf(split[i + 2].replace("]", ""));
                return v;
            }
        }
        throw new IOException(name + " not found " + firstObj);
    }

    private String getFirstObj(byte[] out) throws IOException {
        InputStream data = new ByteArrayInputStream(out);
        Map<String, StringBuilder> objs = readObjs(data);
        return objs.values().iterator().next().toString().replace("\n", "");
    }

    private void checkHintTable(byte[] out) throws IOException {
        String firstObj = getFirstObj(out);
        int hintPos = getArrayValue("/H", firstObj)[0];
        int hintLength = getArrayValue("/H", firstObj)[1];

        InputStream data = new ByteArrayInputStream(out);
        Assert.assertEquals(data.skip(hintPos), hintPos);

        byte[] hintTable = new byte[hintLength];
        Assert.assertEquals(data.read(hintTable), hintLength);
        String hintTableStr = new String(hintTable);

        Assert.assertTrue(hintTableStr.contains("/S "));
        Assert.assertTrue(hintTableStr.contains("/C "));
        Assert.assertTrue(hintTableStr.contains("/E "));
        Assert.assertTrue(hintTableStr.contains("/L "));
        Assert.assertTrue(hintTableStr.contains("/V "));
        Assert.assertTrue(hintTableStr.contains("/O "));
        Assert.assertTrue(hintTableStr.contains("/I "));
        Assert.assertTrue(hintTableStr.contains("/Length "));
        Assert.assertTrue(hintTableStr.contains("stream"));
        Assert.assertTrue(hintTableStr.contains("endstream"));
        Assert.assertTrue(hintTableStr.endsWith("endobj\n"));

        data = new ByteArrayInputStream(hintTable);
        readStart(data);
        int pages = getValue("/N", firstObj);
        readObjectsTable(data, pages);
        readSharedObjectsTable(data);
        Assert.assertEquals(objectLeast, 1);
    }

    private void readObjectsTable(InputStream data, int pages)
            throws IOException {
        objectLeast = read32(data);
        read32(data);
        int bitsDiffObjects = read16(data);
        read32(data);
        int bitsDiffPageLength = read16(data);
        read32(data);
        read16(data);
        read32(data);
        read16(data);
        read16(data);
        read16(data);
        read16(data);
        read16(data);

        objects = new int[pages];
        for (int i = 0; i < pages; i++) {
            objects[i] = objectLeast + readBits(bitsDiffObjects, data);
        }
        for (int i = 0; i < pages; i++) {
            readBits(bitsDiffPageLength, data);
        }
        for (int i = 0; i < pages; i++) {
            readBits(32, data);
        }
    }

    private void readSharedObjectsTable(InputStream str) throws IOException {
        readBits(32, str);
        readBits(32, str);
        readBits(32, str);
        int sharedGroups = readBits(32, str);
        readBits(16, str);
        readBits(32, str);
        int bitsDiffGroupLength = readBits(16, str);
        for (int i = 0; i < sharedGroups; i++) {
            readBits(bitsDiffGroupLength, str);
        }
    }

    private int readBits(int bits, InputStream data) throws IOException {
        if (bits == 32) {
            return read32(data);
        }
        if (bits == 16) {
            return read16(data);
        }
        throw new IOException("Wrong bits");
    }

    private int read32(InputStream data) throws IOException {
        int ch1 = data.read();
        int ch2 = data.read();
        int ch3 = data.read();
        int ch4 = data.read();
        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4));
    }

    private int read16(InputStream data) throws IOException {
        int ch1 = data.read();
        int ch2 = data.read();
        return (ch1 << 8) + (ch2);
    }

    private void readStart(InputStream inputStream) throws IOException {
        StringBuilder sb = new StringBuilder();
        while (inputStream.available() > 0) {
            int data = inputStream.read();
            if (data == '\n') {
                if (sb.toString().equals("stream")) {
                    return;
                }
                sb.setLength(0);
            } else {
                sb.append((char)data);
            }
        }
    }

    public static Map<String, StringBuilder> readObjs(InputStream inputStream) throws IOException {
        Map<String, StringBuilder> objs = new LinkedHashMap<String, StringBuilder>();
        StringBuilder sb = new StringBuilder();
        String key = null;
        while (inputStream.available() > 0) {
            int data = inputStream.read();
            if (data == '\n') {
                if (sb.toString().endsWith(" 0 obj")) {
                    key = sb.toString().trim();
                    objs.put(key, new StringBuilder());
                } else if (key != null) {
                    objs.get(key).append(sb).append("\n");
                }
                sb.setLength(0);
            } else {
                sb.append((char)data);
            }
        }
        return objs;
    }
}
