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

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;
    }
}
