/*******************************************************************************
 * 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;
	}
}
