/*
 * Copyright 2014-present Open Networking Foundation
 *
 * 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 org.onlab.packet;

import com.google.common.collect.ImmutableSet;
import java.util.Arrays;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * The class representing MAC address.
 */
public class MacAddress {

    private static final Pattern MAC_PATTERN = Pattern.compile("^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$");
    /**
     * First MAC address in ONOS OUI range.
     */
    public static final MacAddress ONOS = valueOf("a4:23:05:00:00:00");
    /**
     * Dummy MAC address. We use the first MAC address in ONOS OUI range as the dummy MAC address.
     */
    public static final MacAddress NONE = ONOS;
    /**
     * ONOS LLDP MAC address with multicast bit set.
     */
    public static final MacAddress ONOS_LLDP = valueOf("a5:23:05:00:00:01");
    /**
     * All-zero MAC address.
     */
    public static final MacAddress ZERO = valueOf("00:00:00:00:00:00");
    /**
     * Broadcast MAC address.
     */
    public static final MacAddress BROADCAST = valueOf("ff:ff:ff:ff:ff:ff");
    /**
     * IPv4 multicast MAC address.
     */
    public static final MacAddress IPV4_MULTICAST = valueOf("01:00:5e:00:00:00");
    /**
     * IPv4 multicast MAC mask.
     */
    public static final MacAddress IPV4_MULTICAST_MASK = valueOf("ff:ff:ff:80:00:00");
    /**
     * A set of LLDP MAC addresses.
     */
    public static final Set<MacAddress> LLDP = ImmutableSet.of(
            MacAddress.valueOf("01:80:c2:00:00:00"),
            MacAddress.valueOf("01:80:c2:00:00:03"),
            MacAddress.valueOf("01:80:c2:00:00:0e"));

    public static final int MAC_ADDRESS_LENGTH = 6;
    private byte[] address = new byte[MacAddress.MAC_ADDRESS_LENGTH];

    public MacAddress(final byte[] address) {
        this.address = Arrays.copyOf(address, MacAddress.MAC_ADDRESS_LENGTH);
    }

    /**
     * Returns a MAC address instance representing the value of the specified
     * {@code String}.
     *
     * @param address the String representation of the MAC Address to be parsed.
     * @return a MAC Address instance representing the value of the specified
     * {@code String}.
     * @throws IllegalArgumentException if the string cannot be parsed as a MAC address.
     */
    public static MacAddress valueOf(final String address) {
        if (!isValid(address)) {
            throw new IllegalArgumentException(
                    "Specified MAC Address must contain 12 hex digits"
                            + " separated pairwise by :'s.");
        }
        final String[] elements = address.split(":");
        final byte[] addressInBytes = new byte[MacAddress.MAC_ADDRESS_LENGTH];
        for (int i = 0; i < MacAddress.MAC_ADDRESS_LENGTH; i++) {
            final String element = elements[i];
            addressInBytes[i] = (byte) Integer.parseInt(element, 16);
        }

        return new MacAddress(addressInBytes);
    }

    /**
     * Returns a MAC address instance representing the specified {@code byte}
     * array.
     *
     * @param address the byte array to be parsed.
     * @return a MAC address instance representing the specified {@code byte}
     * array.
     * @throws IllegalArgumentException if the byte array cannot be parsed as a MAC address.
     */
    public static MacAddress valueOf(final byte[] address) {
        if (address.length != MacAddress.MAC_ADDRESS_LENGTH) {
            throw new IllegalArgumentException("the length is not "
                                                       + MacAddress.MAC_ADDRESS_LENGTH);
        }

        return new MacAddress(address);
    }

    /**
     * Returns a MAC address instance representing the specified {@code long}
     * value. The lower 48 bits of the long value are used to parse as a MAC
     * address.
     *
     * @param address the long value to be parsed. The lower 48 bits are used for a
     *                MAC address.
     * @return a MAC address instance representing the specified {@code long}
     * value.
     * @throws IllegalArgumentException if the long value cannot be parsed as a MAC address.
     */
    public static MacAddress valueOf(final long address) {
        final byte[] addressInBytes = new byte[]{
                (byte) (address >> 40 & 0xff), (byte) (address >> 32 & 0xff),
                (byte) (address >> 24 & 0xff), (byte) (address >> 16 & 0xff),
                (byte) (address >> 8 & 0xff), (byte) (address >> 0 & 0xff)};

        return new MacAddress(addressInBytes);
    }

    /**
     * Returns the length of the {@code MACAddress}.
     *
     * @return the length of the {@code MACAddress}.
     */
    public int length() {
        return this.address.length;
    }

    /**
     * Returns the value of the {@code MACAddress} as a {@code byte} array.
     *
     * @return the numeric value represented by this object after conversion to
     * type {@code byte} array.
     */
    public byte[] toBytes() {
        return Arrays.copyOf(this.address, this.address.length);
    }

    /**
     * Returns the value of the {@code MACAddress} as a {@code long}.
     *
     * @return the numeric value represented by this object after conversion to
     * type {@code long}.
     */
    public long toLong() {
        long mac = 0;
        for (int i = 0; i < 6; i++) {
            final long t = (this.address[i] & 0xffL) << (5 - i) * 8;
            mac |= t;
        }
        return mac;
    }

    /**
     * Returns {@code true} if the MAC address is the broadcast address.
     *
     * @return {@code true} if the MAC address is the broadcast address.
     */
    public boolean isBroadcast() {
        for (final byte b : this.address) {
            if (b != -1) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns {@code true} if the MAC address is the multicast address.
     *
     * @return {@code true} if the MAC address is the multicast address.
     */
    public boolean isMulticast() {
        if (this.isBroadcast()) {
            return false;
        }
        return (this.address[0] & 0x01) != 0;
    }

    /**
     * Returns true if this MAC address is link local.
     *
     * @return true if link local
     * @deprecated in Kingfisher release. Link local is not a correct description for
     *             this MAC address. Replaced with {@link #isLldp()}
     */
    @Deprecated
    public boolean isLinkLocal() {
        return isLldp();
    }

    /**
     * Returns true if this MAC address is used by link layer discovery protocol.
     *
     * @return true if this MAC is LLDP MAC.
     */
    public boolean isLldp() {
        return LLDP.contains(this);
    }

    /**
     * Returns true if the Organizationally Unique Identifier (OUI) of this MAC
     * address matches ONOS OUI.
     *
     * @return true if the OUI of this MAC address matches ONOS OUI.
     */
    public boolean isOnos() {
        return Arrays.equals(this.oui(), ONOS.oui());
    }

    /**
     * Returns the Organizationally Unique Identifier (OUI) of this MAC address.
     *
     * @return the OUI of this MAC address.
     */
    public byte[] oui() {
        return Arrays.copyOfRange(this.address, 0, 3);
    }

    @Override
    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        }

        if (!(o instanceof MacAddress)) {
            return false;
        }

        final MacAddress other = (MacAddress) o;
        return Arrays.equals(this.address, other.address);
    }

    @Override
    public int hashCode() {
        return Long.hashCode(toLong());
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder(2 * 6 + 5);
        for (final byte b : this.address) {
            if (builder.length() > 0) {
                builder.append(':');
            }
            builder.append(String.format("%02X", b & 0xFF));
        }
        return builder.toString();
    }

    /**
     * @return MAC address in string representation without colons (useful for
     * radix tree storage)
     */
    public String toStringNoColon() {
        final StringBuilder builder = new StringBuilder();
        for (final byte b : this.address) {
            builder.append(String.format("%02X", b & 0xFF));
        }
        return builder.toString();
    }

    private static boolean isValid(final String mac) {
        Matcher matcher = MAC_PATTERN.matcher(mac);
        return matcher.matches();
    }
}
