/*
 * 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.optical.impl;

import org.onosproject.net.Annotations;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.Port;
import org.onosproject.net.optical.OchPort;
import org.onosproject.net.utils.ForwardingPort;

import com.google.common.annotations.Beta;

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

import java.util.Objects;

/**
 * Implementation of OCh port (Optical Channel).
 * Also referred to as a line side port (L-port) or narrow band port.
 * See ITU G.709 "Interfaces for the Optical Transport Network (OTN)"
 */
@Beta
public class DefaultOchPort extends ForwardingPort implements OchPort {

    // Note: try to avoid direct access to the field, use accessor.
    // We might want to lazily parse annotation in the future
    private final OduSignalType signalType;
    private final boolean isTunable;
    private final OchSignal lambda;

    /**
     * Creates an OCh port in the specified network element.
     *
     * @param base Port
     * @param signalType  ODU signal type
     * @param isTunable   tunable wavelength capability
     * @param lambda      OCh signal
     */
    public DefaultOchPort(Port base,
                          OduSignalType signalType,
                          boolean isTunable,
                          OchSignal lambda) {
        super(base);
        // TODO should this class be parsing annotation to instantiate signalType?
        this.signalType = checkNotNull(signalType);
        this.isTunable = isTunable;
        this.lambda = checkNotNull(lambda);
    }

    @Override
    public Type type() {
        return Type.OCH;
    }

    @Override
    public long portSpeed() {
        return signalType.bitRate();
    }


    @Override
    public Annotations annotations() {
        // FIXME Filter OCh annotations, after confirming that
        // it'll not result in information-loss
        return super.annotations();
    }

    /**
     * Returns ODU signal type.
     *
     * @return ODU signal type
     */
    @Override
    public OduSignalType signalType() {
        return signalType;
    }

    /**
     * Returns true if port is wavelength tunable.
     *
     * @return tunable wavelength capability
     */
    @Override
    public boolean isTunable() {
        return isTunable;
    }

    /**
     * Returns OCh signal.
     *
     * @return OCh signal
     */
    @Override
    public OchSignal lambda() {
        return lambda;
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(),
                            signalType(),
                            isTunable(),
                            lambda());
    }

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

        if (obj != null && getClass() == obj.getClass()) {
            final DefaultOchPort that = (DefaultOchPort) obj;
            return super.toEqualsBuilder(that)
                    .append(this.signalType(), that.signalType())
                    .append(this.isTunable(), that.isTunable())
                    .append(this.lambda(), that.lambda())
                    .isEquals();
        }
        return false;
    }

    @Override
    public String toString() {
        return super.toStringHelper()
                .add("signalType", signalType())
                .add("isTunable", isTunable())
                .add("lambda", lambda())
                .toString();
    }
}
