/**
 * 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.
 */
package org.apache.xml.security.test.dom.encryption;


import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.xml.transform.TransformerFactory;

import org.apache.xml.security.algorithms.JCEMapper;
import org.apache.xml.security.encryption.EncryptedData;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.utils.Constants;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import static org.junit.Assert.assertEquals;

public class EncryptContentTest {

    static org.slf4j.Logger LOG =
        org.slf4j.LoggerFactory.getLogger(EncryptContentTest.class);

    private static final String DATA =
        "<users>\n" +
        "  <user>\n" +
        "    <firstname>Bugs</firstname>\n" +
        "    <lastname>Bunny</lastname>\n" +
        "    <age>34</age>\n" +
        "    <serial>Y10</serial>\n" +
        "  </user>\n" +
        "</users>\n";

    private static final String MULTIPLE_USER_DATA =
        "<users>\n" +
        "  <user>\n" +
        "    <firstname>Bugs</firstname>\n" +
        "    <lastname>Bunny</lastname>\n" +
        "  </user>\n" +
        "  <user>\n" +
        "    <firstname>Daffy</firstname>\n" +
        "    <lastname>Duck</lastname>\n" +
        "  </user>\n" +
        "</users>\n";

    private SecretKey secretKey;
    private boolean haveISOPadding;

    public EncryptContentTest() throws Exception {
        org.apache.xml.security.Init.init();

        byte[] bits192 = "abcdefghijklmnopqrstuvwx".getBytes();
        DESedeKeySpec keySpec = new DESedeKeySpec(bits192);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        secretKey = keyFactory.generateSecret(keySpec);

        TransformerFactory tf = TransformerFactory.newInstance();
        tf.newTransformer();

        // Determine if we have ISO 10126 Padding - needed for Bulk AES or
        // 3DES encryption

        haveISOPadding = false;
        String algorithmId =
            JCEMapper.translateURItoJCEID(
                org.apache.xml.security.utils.EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128
            );

        if (algorithmId != null) {
            try {
                if (Cipher.getInstance(algorithmId) != null) {
                    haveISOPadding = true;
                }
            } catch (NoSuchAlgorithmException nsae) {
                //
            } catch (NoSuchPaddingException nspe) {
                //
            }
        }
    }

    @org.junit.Test
    public void testContentRemoved() throws Exception {
        if (!haveISOPadding) {
            LOG.warn("Test testContentRemoved skipped as necessary algorithms not available");
            return;
        }

        Document doc = null;
        try (InputStream is = new ByteArrayInputStream(DATA.getBytes(StandardCharsets.UTF_8))) {
            doc = XMLUtils.read(is, false);
        }
        NodeList dataToEncrypt = doc.getElementsByTagName("user");

        XMLCipher dataCipher = XMLCipher.getInstance(XMLCipher.TRIPLEDES);
        dataCipher.init(XMLCipher.ENCRYPT_MODE, secretKey);

        for (int i = 0; i < dataToEncrypt.getLength(); i++) {
            dataCipher.doFinal(doc,(Element) dataToEncrypt.item(i), true);
        }

        // Check that user content has been removed
        Element user = (Element) dataToEncrypt.item(0);
        Node child = user.getFirstChild();
        while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
            child = child.getNextSibling();
        }

        // child should be EncryptedData, if not throw exception
        Element childElem = (Element) child;
        if (!"EncryptedData".equals(childElem.getLocalName())) {
            // t.transform(new DOMSource(doc), new StreamResult(System.out));
            throw new Exception("Element content not replaced");
        }

        // there shouldn't be any more children elements
        Node sibling = childElem.getNextSibling();
        while (sibling != null && sibling.getNodeType() != Node.ELEMENT_NODE) {
            sibling = sibling.getNextSibling();
        }

        if (sibling != null) {
            // t.transform(new DOMSource(doc), new StreamResult(System.out));
            throw new Exception("Sibling element content not replaced");
        }

        // t.transform(new DOMSource(doc), new StreamResult(System.out));
    }

    /**
     * See SANTUARIO-301:
     * https://issues.apache.org/jira/browse/SANTUARIO-301
     */
    @org.junit.Test
    public void testMultipleKeyInfoElements() throws Exception {
        if (!haveISOPadding) {
            LOG.warn("Test testMultipleKeyInfoElements skipped as necessary algorithms not available");
            return;
        }

        Document doc = null;
        try (InputStream is = new ByteArrayInputStream(MULTIPLE_USER_DATA.getBytes(StandardCharsets.UTF_8))) {
            doc = XMLUtils.read(is, false);
        }
        NodeList dataToEncrypt = doc.getElementsByTagName("user");

        XMLCipher dataCipher = XMLCipher.getInstance(XMLCipher.TRIPLEDES);
        dataCipher.init(XMLCipher.ENCRYPT_MODE, secretKey);

        KeyInfo keyInfo = new KeyInfo(doc);
        keyInfo.addKeyName("mykey");

        EncryptedData encryptedData = dataCipher.getEncryptedData();
        encryptedData.setKeyInfo(keyInfo);

        for (int i = 0; i < dataToEncrypt.getLength(); i++) {
            dataCipher.doFinal(doc,(Element) dataToEncrypt.item(i), true);
        }

        NodeList keyInfoList = doc.getElementsByTagNameNS(Constants.SignatureSpecNS, "KeyInfo");
        assertEquals(keyInfoList.getLength(), 2);
    }

}