/*
 * Copyright 2016-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.util;

import com.google.common.base.Objects;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
import static org.apache.commons.lang3.ArrayUtils.reverse;

/**
 * Immutable sequence of bytes, assumed to represent a value in {@link
 * ByteOrder#BIG_ENDIAN BIG_ENDIAN} order.
 * <p>
 * Sequences can be created copying from an already existing representation of a
 * sequence of bytes, such as {@link ByteBuffer} or {@code byte[]}; or by
 * copying bytes from a primitive data type, such as {@code long}, {@code int}
 * or {@code short}. In the first case, bytes are assumed to be already given in
 * big-endian order, while in the second case big-endianness is enforced by this
 * class.
 */
public final class ImmutableByteSequence {

    private enum BitwiseOp {
        AND,
        OR,
        XOR
    }

    /*
    Actual bytes are backed by a byte buffer.
    The order of a newly-created byte buffer is always BIG_ENDIAN.
     */
    private ByteBuffer value;

    /**
     * Private constructor. Creates a new byte sequence object backed by the
     * passed ByteBuffer.
     *
     * @param value a byte buffer
     */
    private ImmutableByteSequence(ByteBuffer value) {
        this.value = value;
        // Rewind buffer so it's ready to be read.
        // No write operation should be performed on it from now on.
        this.value.rewind();
    }

    /**
     * Creates a new immutable byte sequence with the same content and order of
     * the passed byte array.
     *
     * @param original a byte array value
     * @return a new immutable byte sequence
     */
    public static ImmutableByteSequence copyFrom(byte[] original) {
        checkArgument(original != null && original.length > 0,
                      "Cannot copy from an empty or null array");
        return new ImmutableByteSequence(
                ByteBuffer.allocate(original.length).put(original));
    }

    /**
     * Creates a new immutable byte sequence with the same content and order of
     * the passed byte array, from/to the given indexes (inclusive).
     *
     * @param original a byte array value
     * @param fromIdx  starting index
     * @param toIdx    ending index
     * @return a new immutable byte sequence
     */
    public static ImmutableByteSequence copyFrom(byte[] original, int fromIdx, int toIdx) {
        checkArgument(original != null && original.length > 0,
                      "Cannot copy from an empty or null array");
        checkArgument(toIdx >= fromIdx && toIdx < original.length, "invalid indexes");
        ByteBuffer buffer = ByteBuffer.allocate((toIdx - fromIdx) + 1);
        for (int i = fromIdx; i <= toIdx; i++) {
            buffer.put(original[i]);
        }
        return new ImmutableByteSequence(buffer);
    }

    /**
     * Creates a new immutable byte sequence copying bytes from the given
     * ByteBuffer {@link ByteBuffer}. If the byte buffer order is not big-endian
     * bytes will be copied in reverse order.
     *
     * @param original a byte buffer
     * @return a new byte buffer object
     */
    public static ImmutableByteSequence copyFrom(ByteBuffer original) {
        checkArgument(original != null && original.capacity() > 0,
                      "Cannot copy from an empty or null byte buffer");

        byte[] bytes = new byte[original.capacity()];

        // copy bytes from original buffer
        original.rewind();
        original.get(bytes);

        if (original.order() == ByteOrder.LITTLE_ENDIAN) {
            // FIXME: this can be improved, e.g. read bytes in reverse order from original
            reverse(bytes);
        }

        return new ImmutableByteSequence(ByteBuffer.wrap(bytes));
    }

    /**
     * Creates a new byte sequence of 8 bytes containing the given long value.
     *
     * @param original a long value
     * @return a new immutable byte sequence
     */
    public static ImmutableByteSequence copyFrom(long original) {
        return new ImmutableByteSequence(
                ByteBuffer.allocate(Long.BYTES).putLong(original));
    }

    /**
     * Creates a new byte sequence of 4 bytes containing the given int value.
     *
     * @param original an int value
     * @return a new immutable byte sequence
     */
    public static ImmutableByteSequence copyFrom(int original) {
        return new ImmutableByteSequence(
                ByteBuffer.allocate(Integer.BYTES).putInt(original));
    }

    /**
     * Creates a new byte sequence of 2 bytes containing the given short value.
     *
     * @param original a short value
     * @return a new immutable byte sequence
     */
    public static ImmutableByteSequence copyFrom(short original) {
        return new ImmutableByteSequence(
                ByteBuffer.allocate(Short.BYTES).putShort(original));
    }

    /**
     * Creates a new byte sequence of 1 byte containing the given value.
     *
     * @param original a byte value
     * @return a new immutable byte sequence
     */
    public static ImmutableByteSequence copyFrom(byte original) {
        return new ImmutableByteSequence(
                ByteBuffer.allocate(Byte.BYTES).put(original));
    }

    /**
     * Creates a new byte sequence of the given size where all bits are 0.
     *
     * @param size number of bytes
     * @return a new immutable byte sequence
     */
    public static ImmutableByteSequence ofZeros(int size) {
        // array is initialized to all 0's by default
        return new ImmutableByteSequence(ByteBuffer.wrap(new byte[size]));
    }

    /**
     * Creates a new byte sequence of the given size where all bits are 1.
     *
     * @param size number of bytes
     * @return a new immutable byte sequence
     */
    public static ImmutableByteSequence ofOnes(int size) {
        byte[] bytes = new byte[size];
        Arrays.fill(bytes, (byte) 0xFF);
        return new ImmutableByteSequence(ByteBuffer.wrap(bytes));
    }

    /**
     * Creates a new byte sequence that is prefixed with specified number of
     * zeros if val = 0 or ones if val = 0xff.
     *
     * @param size       number of total bytes
     * @param prefixBits number of bits in prefix
     * @param val        0 for prefix of zeros; 0xff for prefix of ones
     * @return new immutable byte sequence
     */
    static ImmutableByteSequence prefix(int size, long prefixBits, byte val) {
        checkArgument(val == 0 || val == (byte) 0xff, "Val must be 0 or 0xff");
        byte[] bytes = new byte[size];
        int prefixBytes = (int) (prefixBits / Byte.SIZE);
        Arrays.fill(bytes, 0, prefixBytes, val);
        Arrays.fill(bytes, prefixBytes, bytes.length, (byte) ~val);
        int partialBits = (int) (prefixBits % Byte.SIZE);
        if (partialBits != 0) {
            bytes[prefixBytes] = val == 0 ?
                    (byte) (0xff >> partialBits) : (byte) (0xff << Byte.SIZE - partialBits);
        }
        return new ImmutableByteSequence(ByteBuffer.wrap(bytes));
    }

    /**
     * Creates a new byte sequence that is prefixed with specified number of
     * zeros.
     *
     * @param size       number of total bytes
     * @param prefixBits number of bits in prefix
     * @return new immutable byte sequence
     */
    public static ImmutableByteSequence prefixZeros(int size, long prefixBits) {
        return prefix(size, prefixBits, (byte) 0);
    }

    /**
     * Creates a new byte sequence that is prefixed with specified number of
     * ones.
     *
     * @param size       number of total bytes
     * @param prefixBits number of bits in prefix
     * @return new immutable byte sequence
     */
    public static ImmutableByteSequence prefixOnes(int size, long prefixBits) {
        return prefix(size, prefixBits, (byte) 0xff);
    }

    /**
     * Returns a view of this sequence as a read-only {@link ByteBuffer}.
     * <p>
     * The returned buffer will have position 0, while limit and capacity will
     * be set to this sequence {@link #size()}. The buffer order will be
     * big-endian.
     *
     * @return a read-only byte buffer
     */
    public ByteBuffer asReadOnlyBuffer() {
        // position, limit and capacity set rewind at constructor
        return value.asReadOnlyBuffer();
    }

    /**
     * Gets the number of bytes in this sequence.
     *
     * @return an integer value
     */
    public int size() {
        return this.value.capacity();
    }

    /**
     * Creates a new byte array view of this sequence.
     *
     * @return a new byte array
     */
    public byte[] asArray() {
        ByteBuffer bb = asReadOnlyBuffer();
        byte[] bytes = new byte[size()];
        bb.get(bytes);
        return bytes;
    }

    private ImmutableByteSequence doBitwiseOp(ImmutableByteSequence other, BitwiseOp op) {
        checkArgument(other != null && this.size() == other.size(),
                      "Other sequence must be non null and with same size as this");
        byte[] newBytes = new byte[this.size()];
        byte[] thisBytes = this.asArray();
        byte[] otherBytes = other.asArray();
        for (int i = 0; i < this.size(); i++) {
            switch (op) {
                case AND:
                    newBytes[i] = (byte) (thisBytes[i] & otherBytes[i]);
                    break;
                case OR:
                    newBytes[i] = (byte) (thisBytes[i] | otherBytes[i]);
                    break;
                case XOR:
                    newBytes[i] = (byte) (thisBytes[i] ^ otherBytes[i]);
                    break;
                default:
                    throw new IllegalArgumentException(
                            "Unknown bitwise operator " + op.name());
            }
        }
        return ImmutableByteSequence.copyFrom(newBytes);
    }

    /**
     * Returns a new byte sequence corresponding to the result of a bitwise AND
     * operation between this sequence and the given other, i.e. {@code this &
     * other}.
     *
     * @param other other byte sequence
     * @return new byte sequence
     * @throws IllegalArgumentException if other sequence is null or its size is
     *                                  different than this sequence size
     */
    public ImmutableByteSequence bitwiseAnd(ImmutableByteSequence other) {
        return doBitwiseOp(other, BitwiseOp.AND);
    }

    /**
     * Returns a new byte sequence corresponding to the result of a bitwise OR
     * operation between this sequence and the given other, i.e. {@code this |
     * other}.
     *
     * @param other other byte sequence
     * @return new byte sequence
     * @throws IllegalArgumentException if other sequence is null or its size is
     *                                  different than this sequence size
     */
    public ImmutableByteSequence bitwiseOr(ImmutableByteSequence other) {
        return doBitwiseOp(other, BitwiseOp.OR);
    }

    /**
     * Returns a new byte sequence corresponding to the result of a bitwise XOR
     * operation between this sequence and the given other, i.e. {@code this ^
     * other}.
     *
     * @param other other byte sequence
     * @return new byte sequence
     * @throws IllegalArgumentException if other sequence is null or its size is
     *                                  different than this sequence size
     */
    public ImmutableByteSequence bitwiseXor(ImmutableByteSequence other) {
        return doBitwiseOp(other, BitwiseOp.XOR);
    }

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        final ImmutableByteSequence other = (ImmutableByteSequence) obj;
        return Objects.equal(this.value, other.value);
    }

    /**
     * Returns the index of the most significant bit (MSB), assuming a bit
     * numbering scheme of type "LSB 0", i.e. the bit numbering starts at zero
     * for the least significant bit (LSB). The MSB index of a byte sequence of
     * zeros will be -1.
     * <p>
     * As an example, the following conditions always hold true: {@code
     * ImmutableByteSequence.copyFrom(0).msbIndex() == -1
     * ImmutableByteSequence.copyFrom(1).msbIndex() == 0
     * ImmutableByteSequence.copyFrom(2).msbIndex() == 1
     * ImmutableByteSequence.copyFrom(3).msbIndex() == 1
     * ImmutableByteSequence.copyFrom(4).msbIndex() == 2
     * ImmutableByteSequence.copyFrom(512).msbIndex() == 9 }
     *
     * @return index of the MSB, -1 if the sequence has all bytes set to 0
     */
    public int msbIndex() {
        int index = (size() * 8) - 1;
        byteLoop:
        for (int i = 0; i < size(); i++) {
            byte b = value.get(i);
            if (b != 0) {
                for (int j = 7; j >= 0; j--) {
                    byte mask = (byte) ((1 << j) - 1);
                    if ((b & ~mask) != 0) {
                        break byteLoop;
                    }
                    index--;
                }
            }
            index -= 8;
        }
        return index;
    }

    @Override
    public String toString() {
        return HexString.toHexString(value.array());
    }

    /**
     * Trims or expands a copy of this byte sequence so to fit the given
     * bit-width. When trimming, the operations is deemed to be safe only if the
     * trimmed bits are zero, i.e. it is safe to trim only when {@code bitWidth
     * > msbIndex()}, otherwise an exception will be thrown. When expanding, the
     * sequence will be padded with zeros. The returned byte sequence will have
     * minimum size to contain the given bit-width.
     *
     * @param bitWidth a non-zero positive integer
     * @return a new byte sequence
     * @throws ByteSequenceTrimException if the byte sequence cannot be fitted
     */
    public ImmutableByteSequence fit(int bitWidth) throws ByteSequenceTrimException {
        return doFit(this, bitWidth);
    }

    private static ImmutableByteSequence doFit(ImmutableByteSequence original,
                                               int bitWidth)
            throws ByteSequenceTrimException {

        checkNotNull(original, "byte sequence cannot be null");
        checkArgument(bitWidth > 0, "bit-width must be a non-zero positive integer");

        int newByteWidth = (int) Math.ceil((double) bitWidth / 8);

        if (bitWidth == original.size() * 8) {
            // No need to fit.
            return original;
        }

        ByteBuffer newBuffer = ByteBuffer.allocate(newByteWidth);

        if (newByteWidth > original.size()) {
            // Pad extra bytes with 0's.
            int numPadBytes = newByteWidth - original.size();
            for (int i = 0; i < numPadBytes; i++) {
                newBuffer.put((byte) 0x00);
            }
            newBuffer.put(original.asReadOnlyBuffer());
        } else {
            // Trim sequence.
            if (bitWidth > original.msbIndex()) {
                int diff = original.size() - newByteWidth;
                ByteBuffer originalBuffer = original.asReadOnlyBuffer();
                for (int i = diff; i < original.size(); i++) {
                    newBuffer.put(originalBuffer.get(i));
                }
            } else {
                throw new ByteSequenceTrimException(original, bitWidth);
            }
        }

        return new ImmutableByteSequence(newBuffer);
    }

    /**
     * Signals that a byte sequence cannot be trimmed.
     */
    public static class ByteSequenceTrimException extends Exception {
        ByteSequenceTrimException(ImmutableByteSequence original, int bitWidth) {
            super(format("cannot trim %s into a %d bits long value",
                         original, bitWidth));
        }
    }
}
