/*
 * 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.incubator.net.tunnel;

import static com.google.common.base.MoreObjects.toStringHelper;

import java.util.Objects;
import java.util.Optional;

import com.google.common.annotations.Beta;
import org.onosproject.net.AbstractModel;
import org.onosproject.net.Annotations;
import org.onosproject.net.ElementId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.provider.ProviderId;

/**
 * Default optical tunnel point model implementation.
 */
@Beta
public class DefaultOpticalTunnelEndPoint extends AbstractModel implements OpticalTunnelEndPoint {
    private final Optional<ElementId> elementId;
    private final Optional<PortNumber> portNumber;
    private final Optional<OpticalTunnelEndPoint> parentPoint;
    private final Type type;
    private final OpticalLogicId id;
    private final boolean isGlobal;

    /**
     * Creates a optical tunnel point attributed to the specified provider (may be null).
     * if provider is null, which means the optical tunnel point is not managed by the SB.
     *
     * @param providerId  tunnelProvider Id
     * @param elementId   parent network element
     * @param number      port number
     * @param parentPoint parent port or parent label
     * @param type        port type
     * @param id          LabelId
     * @param isGlobal    indicator whether the label is global significant or not
     * @param annotations optional key/value annotations
     */
    public DefaultOpticalTunnelEndPoint(ProviderId providerId, Optional<ElementId> elementId,
                        Optional<PortNumber> number, Optional<OpticalTunnelEndPoint> parentPoint,
                        Type type, OpticalLogicId id, boolean isGlobal, Annotations... annotations) {
        super(providerId, annotations);
        this.elementId = elementId;
        this.portNumber = number;
        this.parentPoint = parentPoint;
        this.id = id;
        this.type = type;
        this.isGlobal = isGlobal;
    }

    @Override
    public OpticalLogicId id() {
        return id;
    }

    @Override
    public Optional<ElementId> elementId() {
        return elementId;
    }

    @Override
    public Optional<PortNumber> portNumber() {
        return portNumber;
    }

    @Override
    public Optional<OpticalTunnelEndPoint> parentPoint() {
        return parentPoint;
    }

    @Override
    public boolean isGlobal() {
        return isGlobal;
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(elementId, portNumber, parentPoint, id);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof DefaultOpticalTunnelEndPoint) {
            final DefaultOpticalTunnelEndPoint other = (DefaultOpticalTunnelEndPoint) obj;
            return Objects.equals(this.id, other.id) &&
                   Objects.equals(this.type, other.type) &&
                   Objects.equals(this.isGlobal, other.isGlobal) &&
                   Objects.equals(this.elementId, other.elementId) &&
                   Objects.equals(this.portNumber, other.portNumber) &&
                   Objects.equals(this.parentPoint, other.parentPoint);
        }
        return false;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("elementId", elementId)
                .add("portNumber", portNumber)
                .add("parentPoint", parentPoint)
                .add("type", type)
                .add("id", id)
                .add("isGlobal", isGlobal)
                .toString();
    }

}
