/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Nicira ct extension instruction.
 */
public class NiciraCt extends AbstractExtension implements ExtensionTreatment {

    private int flags;
    private long zoneSrc;
    private int zone;
    private short recircTable;
    private int alg;
    private List<ExtensionTreatment> nestedActions;
    private final KryoNamespace appKryo = new KryoNamespace.Builder().build();

    /**
     * Creates a new nicicra ct instruction.
     */
    public NiciraCt() {
        flags = 0;
        zoneSrc = 0L;
        zone = 0;
        alg = 0;
        recircTable = 0xFF;
        nestedActions = new ArrayList<>();
    }

    /**
     * Creates a new nicicra ct instruction.
     * @param flags  zero or commit(0x01)
     * @param zoneSrc If 'zone_src' is nonzero, this specifies that the zone should be
     *                sourced from a field zone_src[ofs:ofs+nbits].
     * @param zone this is the union of zone_imm and zone_ofs_nbits
     *             If 'zone_src' is zero, then the value of 'zone_imm'
     *             will be used as the connection tracking zone
     * @param recircTable  Recirculate to a specific table or 0xff for no recirculation
     * @param alg  Well-known port number for the protocol, 0 indicates no ALG is required
     * @param actions a sequence of zero or more OpenFlow actions
     */
    public NiciraCt(int flags, long zoneSrc, int zone, short recircTable, int alg, List<ExtensionTreatment> actions) {
        this.flags = flags;
        this.zoneSrc = zoneSrc;
        this.zone = zone;
        this.recircTable = recircTable;
        this.alg = alg;
        this.nestedActions = actions;
    }

    @Override
    public ExtensionTreatmentType type() {
        return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT.type();
    }

    /**
     * Get Nicira Conntrack flags.
     * @return flags
     */
    public int niciraCtFlags() {
        return flags;
    }

    /**
     * Get Nicira Conntrack zone.
     * @return zone
     */
    public int niciraCtZone() {
        return zone;
    }

    /**
     * Get Nicira Conntrack zone src.
     * @return zoneSrc
     */
    public long niciraCtZoneSrc() {
        return zoneSrc;
    }

    /**
     * Get Nicira Conntrack alg.
     * @return alg
     */
    public int niciraCtAlg() {
        return alg;
    }

    /**
     * Get Nicira Conntrack Recirc table.
     * @return recirc table
     */
    public short niciraCtRecircTable() {
        return recircTable;
    }

    /**
     * Get Nicira Conntrack Recirc table.
     * @return list extension treatment
     */
    public List<ExtensionTreatment> niciraCtNestActions() {
        return nestedActions;
    }

    @Override
    public void deserialize(byte[] data) {
        Map<String, Object> values = appKryo.deserialize(data);
        flags = (int) values.get("flags");
        zoneSrc = (long) values.get("zoneSrc");
        zone = (int) values.get("zone");
        recircTable = (short) values.get("recircTable");
        alg = (int) values.get("alg");
        nestedActions = (List) values.get("nestedActions");
    }

    @Override
    public byte[] serialize() {
        Map<String, Object> values = Maps.newHashMap();
        values.put("flags", flags);
        values.put("zoneSrc", zoneSrc);
        values.put("zone", zone);
        values.put("recircTable", recircTable);
        values.put("alg", alg);
        values.put("nestedActions", nestedActions);
        return appKryo.serialize(values);
    }

    @Override
    public int hashCode() {
        return Objects.hash(type(), flags, zone, zoneSrc, alg, recircTable, nestedActions);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof NiciraCt) {
            NiciraCt that = (NiciraCt) obj;
            return Objects.equals(flags, that.flags) &&
                    Objects.equals(zone, that.zone) &&
                    Objects.equals(zoneSrc, that.zoneSrc) &&
                    Objects.equals(alg, that.alg) &&
                    Objects.equals(recircTable, that.recircTable) &&
                    Objects.equals(nestedActions, that.nestedActions) &&
                    Objects.equals(this.type(), that.type());
        }
        return false;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("flags", flags)
                .add("zoneSrc", zoneSrc)
                .add("zone", zone)
                .add("recircTable", recircTable)
                .add("alg", alg)
                .add("nestedActions", nestedActions)
                .toString();
    }
}