/*
 * 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 java.util.Map;
import java.util.Objects;

import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;

import com.google.common.base.MoreObjects;
import com.google.common.collect.Maps;

/**
 * Default implementation of Move treatment.
 */
public class DefaultMoveExtensionTreatment extends AbstractExtension
        implements MoveExtensionTreatment {

    private int srcOfs;
    private int dstOfs;
    private int nBits;
    private int src;
    private int dst;
    private ExtensionTreatmentType type;

    private final KryoNamespace appKryo = new KryoNamespace.Builder()
            .register(byte[].class).register(Integer.class).register(Map.class)
            .build();

    /**
     * Creates a new move Treatment.
     *
     * @param srcOfs source offset
     * @param dstOfs destination offset
     * @param nBits nbits
     * @param src source
     * @param dst destination
     * @param type extension treatment type
     */
    public DefaultMoveExtensionTreatment(int srcOfs, int dstOfs, int nBits,
                                         int src, int dst, ExtensionTreatmentType type) {
        this.srcOfs = srcOfs;
        this.dstOfs = dstOfs;
        this.nBits = nBits;
        this.src = src;
        this.dst = dst;
        this.type = type;
    }

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

    @Override
    public byte[] serialize() {
        Map<String, Integer> values = Maps.newHashMap();
        values.put("srcOfs", srcOfs);
        values.put("dstOfs", dstOfs);
        values.put("nBits", nBits);
        values.put("src", src);
        values.put("dst", dst);
        values.put("type", ExtensionTreatmentType.ExtensionTreatmentTypes.valueOf(type.toString()).ordinal());
        return appKryo.serialize(values);
    }

    @Override
    public void deserialize(byte[] data) {
        Map<String, Integer> values = appKryo.deserialize(data);
        srcOfs = values.get("srcOfs");
        dstOfs = values.get("dstOfs");
        nBits = values.get("nBits");
        src = values.get("src");
        dst = values.get("dst");
        type = new ExtensionTreatmentType(values.get("type").intValue());
    }

    @Override
    public int srcOffset() {
        return srcOfs;
    }

    @Override
    public int dstOffset() {
        return dstOfs;
    }

    @Override
    public int src() {
        return src;
    }

    @Override
    public int dst() {
        return dst;
    }

    @Override
    public int nBits() {
        return nBits;
    }

    @Override
    public int hashCode() {
        return Objects.hash(srcOfs, dstOfs, src, dst, nBits);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof DefaultMoveExtensionTreatment) {
            DefaultMoveExtensionTreatment that = (DefaultMoveExtensionTreatment) obj;
            return Objects.equals(srcOfs, that.srcOfs)
                    && Objects.equals(dstOfs, that.dstOfs)
                    && Objects.equals(src, that.src)
                    && Objects.equals(dst, that.dst)
                    && Objects.equals(nBits, that.nBits);

        }
        return false;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass()).add("srcOfs", srcOfs)
                .add("dstOfs", dstOfs).add("nBits", nBits).add("src", src)
                .add("dst", dst).toString();
    }
}
