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

import org.onlab.packet.IGMPMembership;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * Date struct to keep Igmp member infomations.
 */
public final class  GroupMember {

    private final VlanId vlan;
    private final DeviceId deviceId;
    private final PortNumber portNumber;
    private final Ip4Address groupIp;
    private final boolean v2;
    private byte recordType = IGMPMembership.MODE_IS_INCLUDE;
    private ArrayList<Ip4Address> sourceList = new ArrayList<>();
    private int keepAliveQueryInterval = 0;
    private int keepAliveQueryCount = 0;
    private int lastQueryInterval = 0;
    private int lastQueryCount = 0;
    private boolean leave = false;

    public GroupMember(Ip4Address groupIp, VlanId vlan, DeviceId deviceId, PortNumber portNum, boolean isV2) {
        this.groupIp = groupIp;
        this.vlan = vlan;
        this.deviceId = deviceId;
        this.portNumber = portNum;
        v2 = isV2;
    }

    static String getkey(Ip4Address groupIp, DeviceId deviceId, PortNumber portNum) {
        return groupIp.toString() + deviceId.toString() + portNum.toString();
    }

    public String getkey() {
        return GroupMember.getkey(groupIp, deviceId, portNumber);
    }

    public String getId() {
        return getkey();
    }

    public VlanId getvlan() {
        return vlan;
    }

    public DeviceId getDeviceId() {
        return deviceId;
    }

    public PortNumber getPortNumber() {
        return portNumber;
    }

    public Ip4Address getGroupIp() {
        return groupIp;
    }

    public byte getRecordType() {
        return recordType;
    }

    public boolean getv2() {
        return v2;
    }

    public ArrayList<Ip4Address> getSourceList() {
        return sourceList;
    }


    public void updateList(byte recordType, ArrayList<Ip4Address> newSourceList) {
        this.recordType = recordType;
        this.sourceList.clear();
        this.sourceList.addAll(newSourceList);

        /*TODO : support SSM
        if (this.recordType == IGMPMembership.MODE_IS_INCLUDE) {
            switch (recordType) {
                case IGMPMembership.MODE_IS_INCLUDE:
                case IGMPMembership.CHANGE_TO_INCLUDE_MODE:
                    //however , set to include<B> anyway
                    this.sourceList = sourceList;
                    this.recordType = IGMPMembership.MODE_IS_INCLUDE;
                    break;
                case IGMPMembership.MODE_IS_EXCLUDE:
                case IGMPMembership.CHANGE_TO_EXCLUDE_MODE:
                    //set to exclude<B>
                    this.sourceList = sourceList;
                    this.recordType = IGMPMembership.MODE_IS_EXCLUDE;
                    break;
                case IGMPMembership.ALLOW_NEW_SOURCES:
                    //set to include <A+B>
                    join(this.sourceList, sourceList);
                    break;
                case IGMPMembership.BLOCK_OLD_SOURCES:
                    //set to include <A-B>
                    exclude(this.sourceList, sourceList);
                    break;
                default:
                    break;
            }
        } else if (this.recordType == IGMPMembership.MODE_IS_EXCLUDE) {
            switch (recordType) {
                case IGMPMembership.MODE_IS_INCLUDE:
                case IGMPMembership.CHANGE_TO_INCLUDE_MODE:
                    //set to include<B>
                    this.recordType = IGMPMembership.MODE_IS_INCLUDE;
                    this.sourceList = sourceList;
                    break;
                case IGMPMembership.MODE_IS_EXCLUDE:
                case IGMPMembership.CHANGE_TO_EXCLUDE_MODE:
                    this.sourceList = sourceList;
                    this.recordType = IGMPMembership.MODE_IS_EXCLUDE;
                    break;
                case IGMPMembership.ALLOW_NEW_SOURCES:
                    //set to exclude <A-B>
                    exclude(this.sourceList, sourceList);
                    break;
                case IGMPMembership.BLOCK_OLD_SOURCES:
                    //set to exclude <A+B>
                    join(this.sourceList, sourceList);
                    break;
                default:
                    break;
            }
        }*/

        return;
    }


    /*join B to A (A+B)*/
    private void join(ArrayList<Integer> listA, ArrayList<Integer> listB) {
        Iterator<Integer> iterA = null;
        Iterator<Integer> iterB = listB.iterator();
        boolean exists;
        while (iterB.hasNext()) {
            iterA = listA.iterator();
            exists = false;
            int ipToAdd = iterB.next();
            while (iterA.hasNext()) {
                if (iterA.next().equals(ipToAdd)) {
                    exists = true;
                    break;
                }
            }
            if (!exists) {
                listA.add(ipToAdd);
            }
        }
    }

    /* include A and B (A*B)*/
    private void intersection(ArrayList<Integer> listA, ArrayList<Integer> listB) {
        Iterator<Integer> iterA = listA.iterator();
        Iterator<Integer> iterB;
        boolean exists;

        while (iterA.hasNext()) {
            iterB = listB.iterator();
            int ipToInclude = iterA.next();
            exists = false;
            while (iterB.hasNext()) {
                if (iterB.next().equals(ipToInclude)) {
                    exists = true;
                    break;
                }
            }
            if (!exists) {
                iterA.remove();
            }
        }
    }

    /*exclude B from A (A-B)*/
    private void exclude(ArrayList<Integer> listA, ArrayList<Integer> listB) {
        Iterator<Integer> iterA = null;
        Iterator<Integer> iterB = listB.iterator();

        while (iterB.hasNext()) {
            iterA = listA.iterator();
            int ipToDel = iterB.next();
            while (iterA.hasNext()) {
                if (iterA.next().equals(ipToDel)) {
                    iterA.remove();
                    break;
                }
            }
        }
    }

    public void setLeave(boolean l) {
        leave = l;
    }

    public boolean isLeave() {
        return leave;
    }

    public int getKeepAliveQueryInterval() {
        return keepAliveQueryInterval;
    }

    public int getKeepAliveQueryCount() {
        return keepAliveQueryCount;
    }

    public int getLastQueryInterval() {
        return lastQueryInterval;
    }

    public int getLastQueryCount() {
        return lastQueryCount;
    }

    public void keepAliveQueryCount(boolean add) {
        if (add) {
            keepAliveQueryCount++;
        } else {
            keepAliveQueryCount = 0;
        }
    }

    public void lastQueryCount(boolean add) {
        if (add) {
            lastQueryCount++;
        } else {
            lastQueryCount = 0;
        }
    }

    public void keepAliveInterval(boolean add) {
        if (add) {
            keepAliveQueryInterval++;
        } else {
            keepAliveQueryInterval = 0;
        }
    }

    public void lastQueryInterval(boolean add) {
        if (add) {
            lastQueryInterval++;
        } else {
            lastQueryInterval = 0;
        }
    }

    public void resetAllTimers() {
        keepAliveQueryInterval = 0;
        keepAliveQueryCount = 0;
        lastQueryInterval = 0;
        lastQueryCount = 0;
    }
}
