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

import com.google.common.base.MoreObjects;
import org.onlab.packet.Ip4Address;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.instructions.AbstractExtensionInstruction;
import org.onosproject.net.flow.instructions.ExtensionType;
import org.onosproject.store.serializers.Ip4AddressSerializer;

import java.util.Objects;

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

/**
 * Nicira set tunnel destination extension instruction.
 */
public class NiciraSetTunnelDst extends AbstractExtensionInstruction {

    private Ip4Address tunnelDst;

    private final KryoNamespace appKryo = new KryoNamespace.Builder()
            .register(new Ip4AddressSerializer(), Ip4Address.class)
            .register(byte[].class)
            .build();

    /**
     * Creates a new set tunnel destination instruction.
     */
    NiciraSetTunnelDst() {
        tunnelDst = null;
    }

    /**
     * Creates a new set tunnel destination instruction with a particular IPv4
     * address.
     *
     * @param tunnelDst tunnel destination IPv4 address
     */
    NiciraSetTunnelDst(Ip4Address tunnelDst) {
        checkNotNull(tunnelDst);
        this.tunnelDst = tunnelDst;
    }

    /**
     * Gets the tunnel destination IPv4 address.
     *
     * @return tunnel destination IPv4 address
     */
    public Ip4Address tunnelDst() {
        return tunnelDst;
    }

    @Override
    public ExtensionType type() {
        return ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type();
    }

    @Override
    public void deserialize(byte[] data) {
        tunnelDst = appKryo.deserialize(data);
    }

    @Override
    public byte[] serialize() {
        return appKryo.serialize(tunnelDst);
    }

    @Override
    public int hashCode() {
        return Objects.hash(tunnelDst);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof NiciraSetTunnelDst) {
            NiciraSetTunnelDst that = (NiciraSetTunnelDst) obj;
            return Objects.equals(tunnelDst, that.tunnelDst);

        }
        return false;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("tunnelDst", tunnelDst)
                .toString();
    }
}
