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

import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Tunnel class.
 */
public class DefaultTunnel implements Tunnel {

    private final String id;
    private final List<Integer> labelIds;

    private int groupId;
    private boolean allowedToRemoveGroup;

    /**
     * Creates a Tunnel reference.
     *
     * @param tid  Tunnel ID
     * @param labelIds Label stack of the tunnel
     */
    public DefaultTunnel(String tid, List<Integer> labelIds) {
        this.id = checkNotNull(tid);
        this.labelIds = labelIds;
        //TODO: need to register the class in Kryo for this
        //this.labelIds = Collections.unmodifiableList(labelIds);
        this.groupId = -1;
    }

    /**
     * Creates a new DefaultTunnel reference using the tunnel reference.
     *
     * @param tunnel DefaultTunnel reference
     */
    public DefaultTunnel(DefaultTunnel tunnel) {
        this.id = tunnel.id;
        this.labelIds = tunnel.labelIds;
        this.groupId = tunnel.groupId;
    }

    @Override
    public String id() {
        return this.id;
    }

    @Override
    public List<Integer> labelIds() {
        return this.labelIds;
    }

    @Override
    public int groupId() {
        return this.groupId;
    }

    @Override
    public void setGroupId(int id) {
        this.groupId = id;
    }

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

        if (o instanceof DefaultTunnel) {
            DefaultTunnel tunnel = (DefaultTunnel) o;
            // We compare only the tunnel paths.
            if (tunnel.labelIds.equals(this.labelIds)) {
                return true;
            }
        }

        return false;
    }

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

    @Override
    public boolean isAllowedToRemoveGroup() {
        return this.allowedToRemoveGroup;
    }

    @Override
    public void allowToRemoveGroup(boolean b) {
        this.allowedToRemoveGroup = b;
    }
}
