/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed 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.
 */
/*
 * Copyright (c) 2015-2017, The Linux Foundation.
 */
/*
 * Copyright 2013 Giesecke & Devrient GmbH.
 *
 * Licensed 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 com.android.se.internal;

/** Utilities class. */
public final class ByteArrayConverter {

    /** Override the default constructor to make it private. */
    private ByteArrayConverter() {
    }

    /**
     * Forms a FileViewProvider-compatible path String (i.e., transforms the byte array {0x3F, 0x00,
     * 0x2F, 0xE2} into the String "3F00:2FE2").
     *
     * @param rawPath The byte array containing the path component.
     * @return A FileViewProvider-compatible path String.
     * @throws IllegalArgumentException if the path has a bad coding.
     */
    public static String byteArrayToPathString(byte[] rawPath) throws IllegalArgumentException {
        if (rawPath.length % 2 != 0) {
            throw new IllegalArgumentException("Invald path");
        }

        byte[] buffer = new byte[2];
        String path = "";
        for (int i = 0; i < rawPath.length; i += 2) {
            System.arraycopy(rawPath, i, buffer, 0, 2);
            String fid = byteArrayToHexString(buffer);
            if (fid.equalsIgnoreCase("3F00")) {
                // MF should not be included in path
                continue;
            }
            path = path.concat(fid);
            if (i != rawPath.length - 2) {
                path = path.concat(":");
            }
        }
        return path;
    }

    /**
     * Forms an hex-encoded String of the specified byte array.
     *
     * @param array  The byte array to be hex-encoded.
     * @param offset The start position.
     * @param length The number of bytes to be converted.
     * @return A hex-encoded String of the specified byte array.
     */
    public static String byteArrayToHexString(byte[] array, int offset, int length) {
        if (array == null) {
            return "";
        }

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < length; i++) {
            sb.append(String.format("%02x", array[offset + i] & 0xFF));
        }

        return sb.toString();
    }

    /** Converts the byte array to Hex String from a given offset */
    public static String byteArrayToHexString(byte[] array, int offset) {
        StringBuffer s = new StringBuffer();
        for (int i = offset; i < array.length; i++) {
            s.append(Integer.toHexString(0x100 + (array[i] & 0xff)).substring(1));
        }
        return s.toString();
    }

    /**
     * Forms an hex-encoded String of the specified byte array.
     *
     * @param byteArray The byte array to be hex-encoded.
     * @return A hex-encoded String of the specified byte array.
     */
    public static String byteArrayToHexString(byte[] byteArray) {
        if (byteArray == null) {
            return "";
        }
        return byteArrayToHexString(byteArray, 0, byteArray.length);
    }

    /**
     * Forms a byte array containing the values of the hex-encoded string.
     *
     * @param str    The hex-encoded string to be converted to byte-array.
     * @param offset The start position.
     * @param length The number of chars to be converted (must be multiple of 2).
     * @return A byte array containing the values of the hex-encoded string.
     */
    public static byte[] hexStringToByteArray(String str, int offset, int length) {
        if (length % 2 != 0) {
            throw new IllegalArgumentException("length must be multiple of 2");
        }

        str = str.toUpperCase();

        byte[] outputBytes = new byte[str.length() / 2];

        for (int i = 0; i < length; i += 2) {
            char c1 = str.charAt(i + offset);
            char c2 = str.charAt(i + 1 + offset);
            if (!isHexChar(c1) || !isHexChar(c2)) {
                throw new IllegalArgumentException("Invalid char found");
            }

            outputBytes[i / 2] = (byte) ((Character.digit(c1, 16) << 4) + Character.digit(c2, 16));
        }

        return outputBytes;
    }

    /**
     * Forms a byte array containing the values of the hex-encoded string.
     *
     * @param str The hex-encoded string to be converted to byte-array.
     * @return A byte array containing the values of the hex-encoded string.
     */
    public static byte[] hexStringToByteArray(String str) {
        return hexStringToByteArray(str, 0, str.length());
    }

    /**
     * Forms a byte array containing the specified integer value.
     *
     * @param value The integer value to be converted to byte array.
     * @return A byte array containing the specified integer value.
     */
    public static byte[] intToByteArray(int value) {
        return new byte[]{
                (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value
        };
    }

    /**
     * Forms an integer from a byte array.
     *
     * @param byteArray The byte array from where to form the integer.
     * @return The integer value representing the specified byte array. 0 if the array is empty. If
     * the array is longer than 4 bytes, only bytes 0 to 3 will be considered.
     */
    public static int byteArrayToInt(byte[] byteArray) {
        switch (byteArray.length) {
            case 0:
                return 0;
            case 1:
                return (byteArray[0] & 0xFF);
            case 2:
                return (byteArray[0] & 0xFF) << 8 | (byteArray[1] & 0xFF);
            case 3:
                return (byteArray[0] & 0xFF) << 16 | (byteArray[1] & 0xFF) << 8 | (byteArray[2]
                        & 0xFF);
            default:
                return (byteArray[0] & 0xFF) << 24
                        | (byteArray[1] & 0xFF) << 16
                        | (byteArray[2] & 0xFF) << 8
                        | byteArray[3] & 0xFF;
        }
    }

    /**
     * Decides whether a char is a valid hex value or not.
     *
     * @param c The char to be evaluated.
     * @return true if the specified char is a valid hex value, false otherwise.
     */
    public static boolean isHexChar(char c) {
        if (Character.isLowerCase(c)) {
            c = Character.toUpperCase(c);
        }

        return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F');
    }
}
