/*
 * 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.Preconditions.checkNotNull;
import static com.google.common.base.MoreObjects.toStringHelper;

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

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.
 */
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);
        checkNotNull(type, "type cannot be null");
        checkNotNull(id, "id cannot be null");
        checkNotNull(isGlobal, "isGlobal cannot be null");
        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();
    }

}
