/**
 *  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.kerby.kerberos.kerb.crypto;

import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
import org.apache.kerby.kerberos.kerb.crypto.enc.provider.Camellia128Provider;
import org.apache.kerby.kerberos.kerb.crypto.enc.provider.Camellia256Provider;
import org.apache.kerby.util.HexUtil;
import org.junit.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * Ref. camellia-test.c test in MIT krb5 project.
 */
public class CamelliaEncTest {

    private List<String> outputs = new ArrayList<>();

    private byte[] plain = new byte[16];
    private byte[] cipher = new byte[16];
    private EncryptProvider encProvider;

    private List<String> getExpectedLines() throws IOException {
        try (InputStream res = getClass().getResourceAsStream("/camellia-expect-vt.txt");
             BufferedReader br = new BufferedReader(new InputStreamReader(res))) {
            List<String> results = new ArrayList<>();
            String line;
            while ((line = br.readLine()) != null) {
                line = line.trim();
                if (!line.isEmpty()) {
                    results.add(line);
                }
            }
            return results;
        }
    }

    @Test
    public void testEnc() throws IOException, KrbException {
        List<String> expectedLines = getExpectedLines();

        testWith(16);
        outputs.add("==========");
        testWith(32);
        outputs.add("==========");

        List<String> newLines = expectedLines;
        assertThat(newLines).as("Comparing new lines with expected lines").isEqualTo(outputs);
    }

    private void testWith(int keySize) throws KrbException {
        outputs.add("KEYSIZE=" + (keySize * 8));

        encProvider = keySize == 16 ? new Camellia128Provider() : new Camellia256Provider();

        byte[] key = new byte[keySize];
        Arrays.fill(key, (byte) 0);
        hexDump("KEY", key);

        for (int i = 0; i < 16 * 8; ++i) {
            Arrays.fill(plain, (byte) 0);
            setBit(plain, i);
            outputs.add("I=" + (i + 1));
            hexDump("PT", plain);
            encWith(key);
            hexDump("CT", cipher);
        }
    }

    private void hexDump(String label, byte[] bytes) {
        String line = label + "=" + HexUtil.bytesToHex(bytes);
        outputs.add(line);
    }

    private static void setBit(byte[] bytes, int bitnum) {
        int bytenum = bitnum / 8;
        bitnum %= 8;
        // First bit is the high bit!
        bytes[bytenum] = (byte) (1 << (7 - bitnum));
    }

    private void encWith(byte[] key) throws KrbException {
        System.arraycopy(plain, 0, cipher, 0, plain.length);
        encProvider.encrypt(key, cipher);
    }
}
