/*
 * Copyright 2019 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.
 */

package android.net.util;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.MacAddress;

import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Objects;
import java.util.Random;

/**
 * Collection of MAC address utilities.
 * @hide
 */
public final class MacAddressUtils {

    private static final long VALID_LONG_MASK = (1L << 48) - 1;
    private static final long LOCALLY_ASSIGNED_MASK = longAddrFromByteAddr(
            MacAddress.fromString("2:0:0:0:0:0").toByteArray());
    private static final long MULTICAST_MASK = longAddrFromByteAddr(
            MacAddress.fromString("1:0:0:0:0:0").toByteArray());
    private static final long OUI_MASK = longAddrFromByteAddr(
            MacAddress.fromString("ff:ff:ff:0:0:0").toByteArray());
    private static final long NIC_MASK = longAddrFromByteAddr(
            MacAddress.fromString("0:0:0:ff:ff:ff").toByteArray());
    // Matches WifiInfo.DEFAULT_MAC_ADDRESS
    private static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
    private static final int ETHER_ADDR_LEN = 6;

    /**
     * @return true if this MacAddress is a multicast address.
     */
    public static boolean isMulticastAddress(@NonNull MacAddress address) {
        return (longAddrFromByteAddr(address.toByteArray()) & MULTICAST_MASK) != 0;
    }

    /**
     * Returns a generated MAC address whose 46 bits, excluding the locally assigned bit and the
     * unicast bit, are randomly selected.
     *
     * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
     *
     * @return a random locally assigned, unicast MacAddress.
     */
    public static @NonNull MacAddress createRandomUnicastAddress() {
        return createRandomUnicastAddress(null, new SecureRandom());
    }

    /**
     * Returns a randomly generated MAC address using the given Random object and the same
     * OUI values as the given MacAddress.
     *
     * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
     *
     * @param base a base MacAddress whose OUI is used for generating the random address.
     *             If base == null then the OUI will also be randomized.
     * @param r a standard Java Random object used for generating the random address.
     * @return a random locally assigned MacAddress.
     */
    public static @NonNull MacAddress createRandomUnicastAddress(@Nullable MacAddress base,
            @NonNull Random r) {
        long addr;

        if (base == null) {
            addr = r.nextLong() & VALID_LONG_MASK;
        } else {
            addr = (longAddrFromByteAddr(base.toByteArray()) & OUI_MASK)
                    | (NIC_MASK & r.nextLong());
        }
        addr |= LOCALLY_ASSIGNED_MASK;
        addr &= ~MULTICAST_MASK;
        MacAddress mac = MacAddress.fromBytes(byteAddrFromLongAddr(addr));
        if (mac.equals(DEFAULT_MAC_ADDRESS)) {
            return createRandomUnicastAddress(base, r);
        }
        return mac;
    }

    /**
     * Convert a byte address to long address.
     */
    public static long longAddrFromByteAddr(byte[] addr) {
        Objects.requireNonNull(addr);
        if (!isMacAddress(addr)) {
            throw new IllegalArgumentException(
                    Arrays.toString(addr) + " was not a valid MAC address");
        }
        long longAddr = 0;
        for (byte b : addr) {
            final int uint8Byte = b & 0xff;
            longAddr = (longAddr << 8) + uint8Byte;
        }
        return longAddr;
    }

    /**
     * Convert a long address to byte address.
     */
    public static byte[] byteAddrFromLongAddr(long addr) {
        byte[] bytes = new byte[ETHER_ADDR_LEN];
        int index = ETHER_ADDR_LEN;
        while (index-- > 0) {
            bytes[index] = (byte) addr;
            addr = addr >> 8;
        }
        return bytes;
    }

    /**
     * Returns true if the given byte array is a valid MAC address.
     * A valid byte array representation for a MacAddress is a non-null array of length 6.
     *
     * @param addr a byte array.
     * @return true if the given byte array is not null and has the length of a MAC address.
     *
     */
    public static boolean isMacAddress(byte[] addr) {
        return addr != null && addr.length == ETHER_ADDR_LEN;
    }
}
