/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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.onosproject.net;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.Arrays;
import java.util.Objects;

import org.onlab.util.HexString;

import com.google.common.base.MoreObjects;
/**
 * Implementation of ODU Signal ID.
 *
 * <p>
 * See ITU G.709 "Interfaces for the Optical Transport Network (OTN)".
 * </p>
 */
public class OduSignalId {

    private final int tributaryPortNumber;     // Tributary Port number
    private final int tributarySlotLength;        // Number of Tributary Slots included in tsmap
    private final byte[] tributarySlotBitmap; // Tributary slot bitmap

    public static final int TRIBUTARY_SLOT_BITMAP_SIZE = 10;

    /**
     * Creates an instance with the specified arguments.
     *
     * @param tributaryPortNumber   tributary port number
     * @param tributarySlotLen      tributary slot len
     * @param tributarySlotBitmap   tributary slot bitmap
     */
    public OduSignalId(int tributaryPortNumber, int tributarySlotLen,
            byte[] tributarySlotBitmap) {

        checkArgument(tributaryPortNumber <= 80,
                "tributaryPortNumber %s must be <= 80 ",
                 tributaryPortNumber);

        checkArgument(tributarySlotBitmap.length == TRIBUTARY_SLOT_BITMAP_SIZE,
                "number of elements in list " + HexString.toHexString(tributarySlotBitmap)
                + " must be equal to " + TRIBUTARY_SLOT_BITMAP_SIZE);

        checkArgument(tributarySlotLen <= 80,
                "tributarySlotLen %s must be <= 80 ",
                tributarySlotLen);

        this.tributaryPortNumber = tributaryPortNumber;
        this.tributarySlotLength = tributarySlotLen;
        this.tributarySlotBitmap = Arrays.copyOf(tributarySlotBitmap, tributarySlotBitmap.length);
    }

    /**
     * Returns the OduSignalId representing the specified parameters.
     *
     * @param tributaryPortNumber   tributary port number
     * @param tributarySlotLen      tributary slot len
     * @param tributarySlotBitmap   tributary slot bitmap
     * @return OduSignalId
     */
    public static OduSignalId oduSignalId(int tributaryPortNumber, int tributarySlotLen,
            byte[] tributarySlotBitmap) {
        return new OduSignalId(tributaryPortNumber, tributarySlotLen, tributarySlotBitmap);
    }


    /**
     * Returns tributary port number.
     *
     * @return the tributaryPortNumber
     */
    public int tributaryPortNumber() {
        return tributaryPortNumber;
    }

    /**
     * Returns tributary slot length.
     *
     * @return the tributarySlotLen
     */
    public int tributarySlotLength() {
        return tributarySlotLength;
    }

    /**
     * Returns tributary slot bitmap.
     *
     * @return the tributarySlotBitmap
     */
    public byte[] tributarySlotBitmap() {
        return Arrays.copyOf(tributarySlotBitmap, tributarySlotBitmap.length);
    }

    @Override
    public int hashCode() {
        return Objects.hash(tributaryPortNumber, tributarySlotLength, Arrays.hashCode(tributarySlotBitmap));
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof OduSignalId)) {
            return false;
        }
        final OduSignalId other = (OduSignalId) obj;
        return   Objects.equals(this.tributaryPortNumber, other.tributaryPortNumber)
                 && Objects.equals(this.tributarySlotLength, other.tributarySlotLength)
                 && Arrays.equals(tributarySlotBitmap, other.tributarySlotBitmap);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .omitNullValues()
                .add("tributaryPortNumber", tributaryPortNumber)
                .add("tributarySlotLength", tributarySlotLength)
                .add("tributarySlotBitmap", HexString.toHexString(tributarySlotBitmap))
                .toString();
    }

}

