/*
 * 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.io.ByteArrayOutputStream;
import java.io.IOException;

import org.junit.Before;
import org.junit.Test;

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

import org.apache.commons.io.output.CountingOutputStream;

/**
 * Test class for {@link PDFName}.
 */
public class PDFNameTestCase extends PDFObjectTestCase {
    private PDFName pdfName;

    /**
     * Sets up the local variables
     */
    @Before
    public void setUp() {
        pdfName = new PDFName("TestName");
        pdfName.setParent(parent);
        pdfName.setDocument(doc);

        pdfObjectUnderTest = pdfName;
    }

    /**
     * Tests escapeName() - tests that this method escapes the necessary characters.
     */
    @Test
    public void testEscapeName() {
        try {
            // Test for null, this is a programming error thus the NPE
            PDFName.escapeName(null);
            fail("NPE not thrown when null object given to escapeName()");
        } catch (NullPointerException e) {
            // PASS
        }
        // All names are prefixed by "/", check the PDF spec for further details.
        assertEquals("/Test", PDFName.escapeName("Test"));
        // Check that if the name is already prefixed with "/" it doens't do it twice
        assertEquals("/Test", PDFName.escapeName("/Test"));
        // Test with a space in the middle
        assertEquals("/Test#20test", PDFName.escapeName("Test test"));
        // Test that all chars apart from ASCII '!' --> '~' are escaped
        nonEscapedCharactersTests();
        escapedCharactersTests();
    }

    private void escapedCharactersTests() {
        for (char i = 0; i < '!'; i++) {
            String str = Integer.toHexString(i >>> 4 & 0x0f).toUpperCase();
            str += Integer.toHexString(i & 0x0f).toUpperCase();
            assertEquals("/#" + str, PDFName.escapeName(String.valueOf(i)));
        }
        for (char i = '~' + 1; i < 256; i++) {
            String str = Integer.toHexString(i >>> 4 & 0x0f).toUpperCase();
            str += Integer.toHexString(i & 0x0f).toUpperCase();
            assertEquals("/#" + str, PDFName.escapeName(String.valueOf(i)));
        }
        checkCharacterIsEscaped('#');
        checkCharacterIsEscaped('%');
        checkCharacterIsEscaped('(');
        checkCharacterIsEscaped(')');
        checkCharacterIsEscaped('<');
        checkCharacterIsEscaped('>');
        checkCharacterIsEscaped('[');
        checkCharacterIsEscaped(']');
        checkCharacterIsEscaped('>');
    }

    private void checkCharacterIsEscaped(char c) {
        String str = Integer.toHexString(c >>> 4 & 0x0f).toUpperCase();
        str += Integer.toHexString(c & 0x0f).toUpperCase();
        assertEquals("/#" + str, PDFName.escapeName(String.valueOf(c)));
    }

    private void nonEscapedCharactersTests() {
        charactersNotEscapedBetween('!', '"');
        charactersNotEscapedBetween('*', ';');
        charactersNotEscapedBetween('?', 'Z');
        charactersNotEscapedBetween('^', '~');
    }

    private void charactersNotEscapedBetween(char c1, char c2) {
        for (char i = c1; i <= c2; i++) {
            String str = String.valueOf(i);
            String expected = !str.equals("/") ? "/" + str : str;
            assertEquals(expected, PDFName.escapeName(str));
        }
    }

    /**
     * Tests toString() - this has been overridden to return the String that PDFName wraps.
     */
    @Test
    public void testToString() {
        // The escape characters have already been tested in testEscapeName() so this doesn't need
        // to be done twice.
        PDFName test1 = new PDFName("test1");
        assertEquals("/test1", test1.toString());
        PDFName test2 = new PDFName("another test");
        assertEquals("/another#20test", test2.toString());
        try {
            new PDFName(null);
            fail("NPE not thrown when null passed to constructor");
        } catch (NullPointerException e) {
            // PASS
        }
    }

    /**
     * Tests output() - check that this object can stream itself in the correct format.
     * @throws IOException error caused by I/O
     */
    @Test
    public void testOutput() throws IOException {
        testOutputStreams("/TestName", pdfName);
        testOutputStreams("/test#20test", new PDFName("test test"));
    }

    /**
     * Test outputInline() - this writes the object reference if it is a direct object (has an
     * object number), or writes the String representation if there is no object number.
     */
    @Test
    public void testOutputInline() {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        CountingOutputStream cout = new CountingOutputStream(outStream);
        StringBuilder textBuffer = new StringBuilder();
        try {
            // test with no object number set.
            pdfName.outputInline(outStream, textBuffer);
            PDFDocument.flushTextBuffer(textBuffer, cout);
            assertEquals("/TestName", outStream.toString());

            outStream.reset();
            // test with object number set
            pdfName.setObjectNumber(1);
            pdfName.outputInline(outStream, textBuffer);
            PDFDocument.flushTextBuffer(textBuffer, cout);
            assertEquals("1 0 R", outStream.toString());
        } catch (IOException e) {
            fail("IOException: " + e.getMessage());
        }
    }
}
