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

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.InputStream;
import java.util.Arrays;

import junit.framework.TestCase;

/**
 * MODCAParser and MODCAParser.UnparsedStructuredField Unit tests
 */
public class MODCAParserTestCase extends TestCase {

    /** The carriage control character (0x5A) used to indicate the start of a structured field. */
    public static final byte CARRIAGE_CONTROL_CHAR = (byte)0x5A;
    /**ASCII carriage return control character*/
    public static final byte CARRIAGE_RETURN = (byte)0x0A;
    /**ASCII line feed control character */
    public static final byte LINE_FEED = (byte)0x0D;
    /** 8 byte introducer describe the SF */
    private static final int INTRODUCER_LENGTH = 8;

    /**
     * Test that the MODCA parser recognises carriage control (0x5A) as the Structured Field
     * delimeter
     *
     * @throws Exception *
     */
    public void testReadNextStructuredField1() throws Exception {

        // carriage control (0x5A) delimits structured fields,
        // and control is handed to readStructuredField(DataInputStream)
        byte[][] goodInputStream = new byte[][]{
                new byte[]{CARRIAGE_CONTROL_CHAR}
        };

        for (byte[] b : goodInputStream) {
            try {
                new MODCAParser(new ByteArrayInputStream(b))
                        .readNextStructuredField();
                fail("BAD SF should throw EOF: " + byteArrayToString(b));
            } catch (EOFException eof) {
                //passed
            }
        }

        // EOFException thrown when reading the input stream are caught and
        // a null value is returned
        byte[][] badInputStream = new byte[][]{
                new byte[]{},
                new byte[]{CARRIAGE_RETURN},
                new byte[]{LINE_FEED}
        };

        for (byte[] b : badInputStream) {
            UnparsedStructuredField usf = new MODCAParser(new ByteArrayInputStream(b))
            .readNextStructuredField();
            assertNull(usf);
        }
    }


    /**
     * Test that the MODCA parser correctly constructs an UnparsedStructuredField
     * from a well formed structured field
     *
     * @throws Exception *
     */
    public void testReadNextStructuredField2() throws Exception {

        // no extension data
        testSF((byte)0xd3, (byte)0xa8, (byte)0x89, //SFTypeID
                (byte)0, //flags excluding the bits for
                //extension present, segmented data and padding present
                false, false,
                new byte[]{0, 0},
                new byte[]{1}, null);

        // with extension data
        testSF((byte)0xd3, (byte)0xa8, (byte)0x89, //SFTypeID
                (byte)0, //flags excluding the bits for
                //extension present, segmented data and padding present
                false, false,
                new byte[]{0, 0},
                new byte[]{1}, new byte[]{10});

        // with ignored reserved bits
        testSF((byte)0xd3, (byte)0xa8, (byte)0x89, //SFTypeID
                (byte)0, //flags excluding the bits for
                //extension present, segmented data and padding present
                false, false,
                new byte[]{1, 2},
                new byte[]{1}, null);

        // with padding present and segmented data
        testSF((byte)0xd3, (byte)0xa8, (byte)0x89, //SFTypeID
                (byte)(1 << 3), //flags excluding the bits for
                //extension present, segmented data and padding present
                true, true,
                new byte[]{0, 0},
                new byte[]{1}, null);

     // with flags non zero
        testSF((byte)0xd3, (byte)0xa8, (byte)0x89, //SFTypeID
                (byte)(1 << 3), //flags excluding the bits for
                //extension present, segmented data and padding present
                false, false,
                new byte[]{0, 0},
                new byte[]{1}, null);
    }


    private void testSF(byte classCode, byte typeCode, byte categoryCode,
            byte flags, boolean segmentedData, boolean paddingPresent, byte[] reserved,
            byte[] data, byte[] extData) throws Exception {

        byte extDataLength = 0;
        boolean extensionPresent = (extData != null);

        if (extensionPresent) {
            flags = (byte)(flags | 0x01);
            extDataLength = (byte)(extData.length + 1); //length includes length byte
        }

        if (segmentedData) {
            flags = (byte)(flags | 0x04);
        }

        if (paddingPresent) {
            flags = (byte)(flags | 0x10);
        }

        short length = (short)(INTRODUCER_LENGTH + data.length + extDataLength);
        byte[] lengthBytes = new byte[]{(byte)(length >> 8), (byte)(length & 0xFF)};

        byte[] sfBytes = new byte[length];

        //introducer bytes
        sfBytes[0] = lengthBytes[0];
        sfBytes[1] = lengthBytes[1];
        sfBytes[2] = classCode;
        sfBytes[3] = typeCode;
        sfBytes[4] = categoryCode;
        sfBytes[5] = flags;
        sfBytes[6] = reserved[0];
        sfBytes[7] = reserved[1];

        if (extDataLength > 0) {
            sfBytes[8] = (byte)(extData.length + 1);
            System.arraycopy(extData, 0, sfBytes, 9, extData.length);
        }

        System.arraycopy(data, 0, sfBytes, length - data.length, data.length);


        byte[] delimiteredSF = new byte[length + 1];

        delimiteredSF[0] = (byte)0x5A;

        System.arraycopy(sfBytes, 0, delimiteredSF, 1, length);

        InputStream bis = new ByteArrayInputStream(delimiteredSF);

        UnparsedStructuredField actual =  new MODCAParser(bis)
        .readNextStructuredField();

        //check introducer
        assertEquals(length, actual.getSfLength());
        assertEquals(classCode, actual.getSfClassCode());
        assertEquals(typeCode, actual.getSfTypeCode());
        assertEquals(categoryCode, actual.getSfCategoryCode());
        assertEquals(extensionPresent, actual.isSfiExtensionPresent());
        assertEquals(segmentedData, actual.isSfiSegmentedData());
        assertEquals(paddingPresent, actual.isSfiPaddingPresent());

        byte[] introducerData = new byte[]{(byte)(length >> 8), (byte)(length & 0xFF),
                classCode,  typeCode, categoryCode, flags, reserved[0], reserved[1]};

        assertTrue(Arrays.equals(introducerData, actual.getIntroducerData()));

        //check data
        assertTrue(Arrays.equals(data, actual.getData()));

        //check extension data
        if (extData != null) {
            assertTrue(Arrays.equals(extData, actual.getExtData()));
        }
        assertEquals(
                (extData == null) ? 0 : extData.length + 1, // 1 byte for length byte
                        actual.getExtLength());

        assertTrue(Arrays.equals(data, actual.getData()));

        int expectedSfTypeID = ((classCode & 0xFF) << 16)
                | ((typeCode & 0xFF) << 8)
                | (categoryCode & 0xFF);

        assertEquals(expectedSfTypeID, actual.getSfTypeID());

        assertTrue(Arrays.equals(sfBytes, actual.getCompleteFieldAsBytes()));

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        actual.writeTo(baos);
        assertTrue(Arrays.equals(sfBytes, baos.toByteArray()));

    }


    private static String byteArrayToString(byte[] byteArray) {
        StringBuilder sb = new StringBuilder();
        for (byte b : byteArray) {
            sb.append(Integer.toHexString(b & 0xFF)).append(" ");
        }
        return sb.toString();
    }

}
