/*
 * 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 com.google.common.collect.Maps;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;

import java.util.Map;
import java.util.Objects;

/**
 * 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();
    }
}
