/*******************************************************************************
 * Copyright (c) 2006, 2012 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.osgi.internal.signedcontent;

public class Base64 {

	private static final byte equalSign = (byte) '=';

	static char digits[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', //
			'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', //
			'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', //
			'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};

	/**
	 * This method decodes the byte array in base 64 encoding into a char array
	 * Base 64 encoding has to be according to the specification given by the
	 * RFC 1521 (5.2).
	 *
	 * @param data the encoded byte array
	 * @return the decoded byte array
	 */
	public static byte[] decode(byte[] data) {
		if (data.length == 0)
			return data;
		int lastRealDataIndex = data.length - 1;
		while (data[lastRealDataIndex] == equalSign)
			lastRealDataIndex--;
		// original data digit is 8 bits long, but base64 digit is 6 bits long
		int padBytes = data.length - 1 - lastRealDataIndex;
		int byteLength = data.length * 6 / 8 - padBytes;
		byte[] result = new byte[byteLength];
		// Each 4 bytes of input (encoded) we end up with 3 bytes of output
		int dataIndex = 0;
		int resultIndex = 0;
		int allBits = 0;
		// how many result chunks we can process before getting to pad bytes
		int resultChunks = (lastRealDataIndex + 1) / 4;
		for (int i = 0; i < resultChunks; i++) {
			allBits = 0;
			// Loop 4 times gathering input bits (4 * 6 = 24)
			for (int j = 0; j < 4; j++)
				allBits = (allBits << 6) | decodeDigit(data[dataIndex++]);
			// Loop 3 times generating output bits (3 * 8 = 24)
			for (int j = resultIndex + 2; j >= resultIndex; j--) {
				result[j] = (byte) (allBits & 0xff); // Bottom 8 bits
				allBits = allBits >>> 8;
			}
			resultIndex += 3; // processed 3 result bytes
		}
		// Now we do the extra bytes in case the original (non-encoded) data
		// was not multiple of 3 bytes
		switch (padBytes) {
			case 1 :
				// 1 pad byte means 3 (4-1) extra Base64 bytes of input, 18
				// bits, of which only 16 are meaningful
				// Or: 2 bytes of result data
				allBits = 0;
				// Loop 3 times gathering input bits
				for (int j = 0; j < 3; j++)
					allBits = (allBits << 6) | decodeDigit(data[dataIndex++]);
				// NOTE - The code below ends up being equivalent to allBits =
				// allBits>>>2
				// But we code it in a non-optimized way for clarity
				// The 4th, missing 6 bits are all 0
				allBits = allBits << 6;
				// The 3rd, missing 8 bits are all 0
				allBits = allBits >>> 8;
				// Loop 2 times generating output bits
				for (int j = resultIndex + 1; j >= resultIndex; j--) {
					result[j] = (byte) (allBits & 0xff); // Bottom 8
					// bits
					allBits = allBits >>> 8;
				}
				break;
			case 2 :
				// 2 pad bytes mean 2 (4-2) extra Base64 bytes of input, 12 bits
				// of data, of which only 8 are meaningful
				// Or: 1 byte of result data
				allBits = 0;
				// Loop 2 times gathering input bits
				for (int j = 0; j < 2; j++)
					allBits = (allBits << 6) | decodeDigit(data[dataIndex++]);
				// NOTE - The code below ends up being equivalent to allBits =
				// allBits>>>4
				// But we code it in a non-optimized way for clarity
				// The 3rd and 4th, missing 6 bits are all 0
				allBits = allBits << 6;
				allBits = allBits << 6;
				// The 3rd and 4th, missing 8 bits are all 0
				allBits = allBits >>> 8;
				allBits = allBits >>> 8;
				result[resultIndex] = (byte) (allBits & 0xff); // Bottom
				// 8
				// bits
				break;
		}
		return result;
	}

	/**
	 * This method converts a Base 64 digit to its numeric value.
	 *
	 * @param data digit (character) to convert
	 * @return value for the digit
	 */
	static int decodeDigit(byte data) {
		char charData = (char) data;
		if (charData <= 'Z' && charData >= 'A')
			return charData - 'A';
		if (charData <= 'z' && charData >= 'a')
			return charData - 'a' + 26;
		if (charData <= '9' && charData >= '0')
			return charData - '0' + 52;
		switch (charData) {
			case '+' :
				return 62;
			case '/' :
				return 63;
			default :
				throw new IllegalArgumentException("Invalid char to decode: " + data); //$NON-NLS-1$
		}
	}

	/**
	 * This method encodes the byte array into a char array in base 64 according
	 * to the specification given by the RFC 1521 (5.2).
	 *
	 * @param data the encoded char array
	 * @return the byte array that needs to be encoded
	 */
	public static byte[] encode(byte[] data) {
		int sourceChunks = data.length / 3;
		int len = ((data.length + 2) / 3) * 4;
		byte[] result = new byte[len];
		int extraBytes = data.length - (sourceChunks * 3);
		// Each 4 bytes of input (encoded) we end up with 3 bytes of output
		int dataIndex = 0;
		int resultIndex = 0;
		int allBits = 0;
		for (int i = 0; i < sourceChunks; i++) {
			allBits = 0;
			// Loop 3 times gathering input bits (3 * 8 = 24)
			for (int j = 0; j < 3; j++)
				allBits = (allBits << 8) | (data[dataIndex++] & 0xff);
			// Loop 4 times generating output bits (4 * 6 = 24)
			for (int j = resultIndex + 3; j >= resultIndex; j--) {
				result[j] = (byte) digits[(allBits & 0x3f)]; // Bottom
				// 6
				// bits
				allBits = allBits >>> 6;
			}
			resultIndex += 4; // processed 4 result bytes
		}
		// Now we do the extra bytes in case the original (non-encoded) data
		// is not multiple of 4 bytes
		switch (extraBytes) {
			case 1 :
				allBits = data[dataIndex++]; // actual byte
				allBits = allBits << 8; // 8 bits of zeroes
				allBits = allBits << 8; // 8 bits of zeroes
				// Loop 4 times generating output bits (4 * 6 = 24)
				for (int j = resultIndex + 3; j >= resultIndex; j--) {
					result[j] = (byte) digits[(allBits & 0x3f)]; // Bottom
					// 6
					// bits
					allBits = allBits >>> 6;
				}
				// 2 pad tags
				result[result.length - 1] = (byte) '=';
				result[result.length - 2] = (byte) '=';
				break;
			case 2 :
				allBits = data[dataIndex++]; // actual byte
				allBits = (allBits << 8) | (data[dataIndex++] & 0xff); // actual
				// byte
				allBits = allBits << 8; // 8 bits of zeroes
				// Loop 4 times generating output bits (4 * 6 = 24)
				for (int j = resultIndex + 3; j >= resultIndex; j--) {
					result[j] = (byte) digits[(allBits & 0x3f)]; // Bottom
					// 6
					// bits
					allBits = allBits >>> 6;
				}
				// 1 pad tag
				result[result.length - 1] = (byte) '=';
				break;
		}
		return result;
	}
}
