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

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;

import org.junit.Before;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import static org.junit.Assert.assertTrue;

import org.apache.fop.util.DigestFilter;

/**
 * Test case for digesting SAX filter.
 *
 */
public class DigestFilterTestCase {

    private SAXParserFactory parserFactory;

    @Before
    public void setUp() {
        parserFactory = SAXParserFactory.newInstance();
        parserFactory.setNamespaceAware(true);
    }

    private boolean compareDigest(byte[] a, byte[] b) {
        if (a.length != b.length) {
            return false;
        }
        for (int i = 0; i < a.length; i++) {
            if (a[i] != b[i]) {
                return false;
            }
        }
        return true;
    }

    private String digestToString(byte[] digest) {
        StringBuffer buffer = new StringBuffer(2 * digest.length);
        for (int i = 0; i < digest.length; i++) {
            int val = digest[i];
            int hi = (val >> 4) & 0xF;
            int lo = val & 0xF;
            if (hi < 10) {
                buffer.append((char) (hi + 0x30));
            } else {
                buffer.append((char) (hi + 0x61 - 10));
            }
            if (lo < 10) {
                buffer.append((char) (lo + 0x30));
            } else {
                buffer.append((char) (lo + 0x61 - 10));
            }
        }
        return buffer.toString();
    }

    private byte[] runTest(String input)
        throws
            NoSuchAlgorithmException,
            ParserConfigurationException,
            SAXException,
            IOException {
        XMLReader parser = parserFactory.newSAXParser().getXMLReader();
        DigestFilter digestFilter = new DigestFilter("MD5");
        digestFilter.setParent(parser);
        digestFilter.setFeature("http://xml.org/sax/features/namespaces", true);
        parser.setContentHandler(digestFilter);
        InputSource inputSource = new InputSource(new StringReader(input));
        parser.parse(inputSource);
        return digestFilter.getDigestValue();
    }

    @Test
    public final void testLineFeed()
        throws
            NoSuchAlgorithmException,
            ParserConfigurationException,
            SAXException,
            IOException {
        byte[] lfDigest = runTest("<a>\n</a>");
        byte[] crlfDigest = runTest("<a>\r\n</a>");
        assertTrue(
            "LF: "
                + digestToString(lfDigest)
                + " CRLF: "
                + digestToString(crlfDigest),
            compareDigest(lfDigest, crlfDigest));
    }

    @Test
    public final void testAttributeOrder()
        throws
            NoSuchAlgorithmException,
            ParserConfigurationException,
            SAXException,
            IOException {
        byte[] sortDigest = runTest("<a a1='1' a2='2' a3='3'/>");
        byte[] permutationDigest = runTest("<a a2='2' a3='3' a1='1'/>");
        assertTrue(
            "Sort: "
                + digestToString(sortDigest)
                + " permuted: "
                + digestToString(permutationDigest),
            compareDigest(sortDigest, permutationDigest));
        byte[] reverseDigest = runTest("<a a3='3' a2='2' a1='1'/>");
        assertTrue(
            "Sort: "
                + digestToString(sortDigest)
                + " permuted: "
                + digestToString(reverseDigest),
            compareDigest(sortDigest, reverseDigest));
    }

    @Test
    public final void testNamespacePrefix()
        throws
            NoSuchAlgorithmException,
            ParserConfigurationException,
            SAXException,
            IOException {
        byte[] prefix1Digest = runTest("<a:a xmlns:a='foo'/>");
        byte[] prefix2Digest = runTest("<b:a xmlns:b='foo'/>");
        assertTrue(
            "prefix1: "
                + digestToString(prefix1Digest)
                + " prefix2: "
                + digestToString(prefix2Digest),
            compareDigest(prefix1Digest, prefix2Digest));
    }

}
