/*
* Copyright 2022-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 application

import (
	"encoding/json"
	"errors"
	"net"
	"strconv"
	"strings"
	"sync"

	cntlr "voltha-go-controller/internal/pkg/controller"
	"voltha-go-controller/internal/pkg/types"
	"voltha-go-controller/database"
	"voltha-go-controller/internal/pkg/of"
	"voltha-go-controller/internal/pkg/util"
	"voltha-go-controller/log"
)

// ------------------------------------------------------------
// MVLAN related implemnetation
//
// Each MVLAN is configured with groups of multicast IPs. The idea of
// groups is to be able to group some multicast channels into an individual
// PON group and have a unique multicast GEM port for that set. However, in
// the current implementation, the concept of grouping is not fully utilized.

// MvlanGroup structure
// A set of MC IPs form a group

// MCGroupProxy identifies source specific multicast(SSM) config.
type MCGroupProxy struct {
        // Mode represents source list include/exclude
        Mode common.MulticastSrcListMode
        // SourceList represents list of multicast server IP addresses.
        SourceList []net.IP
}

// MvlanGroup identifies MC group info
type MvlanGroup struct {
        Name     string
        Wildcard bool
        McIPs    []string
        IsStatic bool
}

// OperInProgress type
type OperInProgress uint8

const (
        // UpdateInProgress constant
        UpdateInProgress OperInProgress = 2
        // NoOp constant
        NoOp OperInProgress = 1
        // Nil constant
        Nil OperInProgress = 0
)

// MvlanProfile : A set of groups of MC IPs for a MVLAN profile. It is assumed that
// the MVLAN IP is not repeated within multiples groups and across
// MVLAN profiles. The first match is used up on search to lcoate the
// MVLAN profile for an MC IP
type MvlanProfile struct {
        Name                string
        Mvlan               of.VlanType
        PonVlan             of.VlanType
        Groups              map[string]*MvlanGroup
        Proxy               map[string]*MCGroupProxy
        Version             string
        IsPonVlanPresent    bool
        IsChannelBasedGroup bool
        DevicesList         map[string]OperInProgress //device serial number //here
        oldGroups           map[string]*MvlanGroup
        oldProxy            map[string]*MCGroupProxy
        MaxActiveChannels   uint32
        PendingDeleteFlow   map[string]map[string]bool
        DeleteInProgress    bool
        IgmpServVersion     map[string]*uint8
        mvpLock             sync.RWMutex
        mvpFlowLock         sync.RWMutex
}

// NewMvlanProfile is constructor for MVLAN profile.
func NewMvlanProfile(name string, mvlan of.VlanType, ponVlan of.VlanType, isChannelBasedGroup bool, OLTSerialNums []string, actChannelPerPon uint32) *MvlanProfile {
        var mvp MvlanProfile
        mvp.Name = name
        mvp.Mvlan = mvlan
        mvp.PonVlan = ponVlan
        mvp.mvpLock = sync.RWMutex{}
        mvp.Groups = make(map[string]*MvlanGroup)
        mvp.Proxy = make(map[string]*MCGroupProxy)
        mvp.DevicesList = make(map[string]OperInProgress)
        mvp.PendingDeleteFlow = make(map[string]map[string]bool)
        mvp.IsChannelBasedGroup = isChannelBasedGroup
        mvp.MaxActiveChannels = actChannelPerPon
        mvp.DeleteInProgress = false
        mvp.IgmpServVersion = make(map[string]*uint8)

        if (ponVlan != of.VlanNone) && (ponVlan != 0) {
                mvp.IsPonVlanPresent = true
        }
        return &mvp
}

// AddMvlanProxy for addition of groups to an MVLAN profile
func (mvp *MvlanProfile) AddMvlanProxy(name string, proxyInfo common.MulticastGroupProxy) {
        proxy := &MCGroupProxy{}
        proxy.Mode = proxyInfo.Mode
        proxy.SourceList = util.GetExpIPList(proxyInfo.SourceList)

        if _, ok := mvp.Proxy[name]; !ok {
                logger.Debugw(ctx, "Added MVLAN Proxy", log.Fields{"Name": name, "Proxy": proxy})
        } else {
                logger.Debugw(ctx, "Updated MVLAN Proxy", log.Fields{"Name": name, "Proxy": proxy})
        }
        if proxyInfo.IsStatic == common.IsStaticYes {
                mvp.Groups[name].IsStatic = true
        }
        mvp.Proxy[name] = proxy
}

// AddMvlanGroup for addition of groups to an MVLAN profile
func (mvp *MvlanProfile) AddMvlanGroup(name string, ips []string) {
        mvg := &MvlanGroup{}
        mvg.Name = name
        mvg.Wildcard = len(ips) == 0
        mvg.McIPs = ips
        mvg.IsStatic = false
        if _, ok := mvp.Groups[name]; !ok {
                logger.Debugw(ctx, "Added MVLAN Group", log.Fields{"VLAN": mvp.Mvlan, "Name": name, "mvg": mvg, "IPs": mvg.McIPs})
        } else {
                logger.Debugw(ctx, "Updated MVLAN Group", log.Fields{"VLAN": mvp.Mvlan, "Name": name})
        }
        mvp.Groups[name] = mvg
}

// GetUsMatchVlan provides mvlan for US Match parameter
func (mvp *MvlanProfile) GetUsMatchVlan() of.VlanType {
        if mvp.IsPonVlanPresent {
                return mvp.PonVlan
        }
        return mvp.Mvlan
}

// WriteToDb is utility to write Mvlan Profile Info to database
func (mvp *MvlanProfile) WriteToDb() error {

        if mvp.DeleteInProgress {
                logger.Warnw(ctx, "Skipping Redis Update for MvlanProfile, MvlanProfile delete in progress", log.Fields{"Mvlan": mvp.Mvlan})
                return nil
        }

        mvp.Version = database.PresentVersionMap[database.MvlanPath]
        b, err := json.Marshal(mvp)
        if err != nil {
                return err
        }
        if err1 := db.PutMvlan(uint16(mvp.Mvlan), string(b)); err1 != nil {
                return err1
        }
        return nil
}

//isChannelStatic - Returns true if the given channel is part of static group in the Mvlan Profile
func (mvp *MvlanProfile) isChannelStatic(channel net.IP) bool {
        for _, mvg := range mvp.Groups {
                if mvg.IsStatic {
                        if isChannelStatic := doesIPMatch(channel, mvg.McIPs); isChannelStatic {
                                return true
                        }
                }
        }
        return false
}

//containsStaticChannels - Returns if any static channels is part of the Mvlan Profile
func (mvp *MvlanProfile) containsStaticChannels() bool {
        for _, mvg := range mvp.Groups {
                if mvg.IsStatic && len(mvg.McIPs) != 0 {
                        return true
                }
        }
        return false
}

//getAllStaticChannels - Returns all static channels in the Mvlan Profile
func (mvp *MvlanProfile) getAllStaticChannels() ([]net.IP, bool) {
        channelList := []net.IP{}
        containsStatic := false
        for _, mvg := range mvp.Groups {
                if mvg.IsStatic {
                        staticChannels, _ := mvg.getAllChannels()
                        channelList = append(channelList, staticChannels...)
                }
        }
        if len(channelList) > 0 {
                containsStatic = true
        }
        return channelList, containsStatic
}

//getAllOldGroupStaticChannels - Returns all static channels in the Mvlan Profile
func (mvp *MvlanProfile) getAllOldGroupStaticChannels() ([]net.IP, bool) {
        channelList := []net.IP{}
        containsStatic := false
        for _, mvg := range mvp.oldGroups {
                if mvg.IsStatic {
                        staticChannels, _ := mvg.getAllChannels()
                        channelList = append(channelList, staticChannels...)
                }
        }
        if len(channelList) > 0 {
                containsStatic = true
        }
        return channelList, containsStatic
}

//getAllChannels - Returns all channels in the Mvlan Profile
func (mvg *MvlanGroup) getAllChannels() ([]net.IP, bool) {
        channelList := []net.IP{}

        if mvg == nil || len(mvg.McIPs) == 0 {
                return []net.IP{}, false
        }

        grpChannelOrRange := mvg.McIPs
        for _, channelOrRange := range grpChannelOrRange {
                if strings.Contains(channelOrRange, "-") {
                        var splits = strings.Split(channelOrRange, "-")
                        ipStart := util.IP2LongConv(net.ParseIP(splits[0]))
                        ipEnd := util.IP2LongConv(net.ParseIP(splits[1]))

                        for i := ipStart; i <= ipEnd; i++ {
                                channelList = append(channelList, util.Long2ipConv(i))
                        }
                } else {
                        channelList = append(channelList, net.ParseIP(channelOrRange))
                }
        }
        return channelList, true
}

//SetUpdateStatus - Sets profile update status for devices
func (mvp *MvlanProfile) SetUpdateStatus(serialNum string, status OperInProgress) {
        if serialNum != "" {
                mvp.DevicesList[serialNum] = status
                return
        }

        for srNo := range mvp.DevicesList {
                mvp.DevicesList[srNo] = status
        }
}

//isUpdateInProgress - checking is update is in progress for the mvlan profile
func (mvp *MvlanProfile) isUpdateInProgress() bool {

        for srNo := range mvp.DevicesList {
                if mvp.DevicesList[srNo] == UpdateInProgress {
                        return true
                }
        }
        return false
}

//IsUpdateInProgressForDevice - Checks is Mvlan Profile update is is progress for the given device
func (mvp *MvlanProfile) IsUpdateInProgressForDevice(device string) bool {
        if vd := GetApplication().GetDevice(device); vd != nil {
                if mvp.DevicesList[vd.SerialNum] == UpdateInProgress {
                        return true
                }
        }
        return false
}

// DelFromDb to delere mvlan from database
func (mvp *MvlanProfile) DelFromDb() {
        _ = db.DelMvlan(uint16(mvp.Mvlan))
}

//DelFlows - Triggers flow deletion after registering for flow indication event
func (mvp *MvlanProfile) DelFlows(device *VoltDevice, flow *of.VoltFlow) error {
        mvp.mvpFlowLock.Lock()
        defer mvp.mvpFlowLock.Unlock()

        var flowMap map[string]bool
        var ok bool

        for cookie := range flow.SubFlows {
                cookie := strconv.FormatUint(cookie, 10)
                fe := &FlowEvent{
                        eType:     EventTypeMcastFlowRemoved,
                        device:    device.Name,
                        cookie:    cookie,
                        eventData: mvp,
                }
                device.RegisterFlowDelEvent(cookie, fe)

                if flowMap, ok = mvp.PendingDeleteFlow[device.Name]; !ok {
                        flowMap = make(map[string]bool)
                }
                flowMap[cookie] = true
                mvp.PendingDeleteFlow[device.Name] = flowMap
        }
        if err := mvp.WriteToDb(); err != nil {
                logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
        }
        return cntlr.GetController().DelFlows(device.NniPort, device.Name, flow)
}

//FlowRemoveSuccess - Process flow success indication
func (mvp *MvlanProfile) FlowRemoveSuccess(cookie string, device string) {
        mvp.mvpFlowLock.Lock()
        defer mvp.mvpFlowLock.Unlock()

        logger.Infow(ctx, "Mvlan Flow Remove Success Notification", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "Device": device})

        if _, ok := mvp.PendingDeleteFlow[device]; ok {
                delete(mvp.PendingDeleteFlow[device], cookie)
        }

        if err := mvp.WriteToDb(); err != nil {
                logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
        }
}

//FlowRemoveFailure - Process flow failure indication
func (mvp *MvlanProfile) FlowRemoveFailure(cookie string, device string, errorCode uint32, errReason string) {

        mvp.mvpFlowLock.Lock()
        defer mvp.mvpFlowLock.Unlock()

        if flowMap, ok := mvp.PendingDeleteFlow[device]; ok {
                if _, ok := flowMap[cookie]; ok {
                        logger.Errorw(ctx, "Mvlan Flow Remove Failure Notification", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason, "Device": device})
                        return
                }
        }
        logger.Errorw(ctx, "Mvlan Flow Del Failure Notification for Unknown cookie", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason})

}

// IsStaticGroup to check if group is static
func (mvp *MvlanProfile) IsStaticGroup(groupName string) bool {
        return mvp.Groups[groupName].IsStatic
}

// generateGroupKey to generate group key
func (mvp *MvlanProfile) generateGroupKey(name string, ipAddr string) string {
        if mvp.IsChannelBasedGroup {
                return mvp.Mvlan.String() + "_" + ipAddr
        }
        return mvp.Mvlan.String() + "_" + name
}

// GetStaticGroupName to get static igmp group
func (mvp *MvlanProfile) GetStaticGroupName(gip net.IP) string {
        for _, mvg := range mvp.Groups {
                if mvg.IsStatic {
                        if doesIPMatch(gip, mvg.McIPs) {
                                return mvg.Name
                        }
                }
        }
        return ""
}

// GetStaticIgmpGroup to get static igmp group
func (mvp *MvlanProfile) GetStaticIgmpGroup(gip net.IP) *IgmpGroup {

        staticGroupName := mvp.GetStaticGroupName(gip)
        grpKey := mvp.generateGroupKey(staticGroupName, gip.String())
        logger.Debugw(ctx, "Get Static IGMP Group", log.Fields{"Group": grpKey})
        ig, ok := GetApplication().IgmpGroups.Load(grpKey)
        if ok {
                logger.Debugw(ctx, "Get Static IGMP Group Success", log.Fields{"Group": grpKey})
                return ig.(*IgmpGroup)
        }
        return nil
}

//pushIgmpMcastFlows - Adds all IGMP related flows (generic DS flow & static group flows)
func (mvp *MvlanProfile) pushIgmpMcastFlows(OLTSerialNum string) {

        mvp.mvpLock.RLock()
        defer mvp.mvpLock.RUnlock()

        if mvp.DevicesList[OLTSerialNum] == Nil {
                logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": OLTSerialNum, "Mvlan": mvp.Mvlan})
                return
        }

        d := GetApplication().GetDeviceBySerialNo(OLTSerialNum)
        if d == nil {
                logger.Warnw(ctx, "Skipping Igmp & Mcast Flow processing: Device Not Found", log.Fields{"Device_SrNo": OLTSerialNum, "Mvlan": mvp.Mvlan})
                return
        }

        p := d.GetPort(d.NniPort)

        if p != nil && p.State == PortStateUp {
                logger.Infow(ctx, "NNI Port Status is: UP & Vlan Enabled", log.Fields{"Device": d, "port": p})

                //Push Igmp DS Control Flows
                err := mvp.ApplyIgmpDSFlowForMvp(d.Name)
                if err != nil {
                        logger.Errorw(ctx, "DS IGMP Flow Add Failed for device",
                                log.Fields{"Reason": err.Error(), "device": d.Name})
                }

                //Trigger Join for static channels
                if channelList, containsStatic := mvp.getAllStaticChannels(); containsStatic {
                        mvp.ProcessStaticGroup(d.Name, channelList, true)
                } else {
                        logger.Infow(ctx, "No Static Channels Present", log.Fields{"mvp": mvp.Name, "Mvlan": mvp.Mvlan})
                }
        }
}
//removeIgmpMcastFlows - Removes all IGMP related flows (generic DS flow & static group flows)
func (mvp *MvlanProfile) removeIgmpMcastFlows(oltSerialNum string) {

        mvp.mvpLock.RLock()
        defer mvp.mvpLock.RUnlock()

        if d := GetApplication().GetDeviceBySerialNo(oltSerialNum); d != nil {
                p := d.GetPort(d.NniPort)
                if p != nil {
                        logger.Infow(ctx, "NNI Port Status is: UP", log.Fields{"Device": d, "port": p})

                        // ***Do not change the order***
                        // When Vlan is disabled, the process end is determined by the DS Igmp flag in device

                        //Trigger Leave for static channels
                        if channelList, containsStatic := mvp.getAllStaticChannels(); containsStatic {
                                mvp.ProcessStaticGroup(d.Name, channelList, false)
                        } else {
                                logger.Infow(ctx, "No Static Channels Present", log.Fields{"mvp": mvp.Name, "Mvlan": mvp.Mvlan})
                        }

                        //Remove all dynamic members for the Mvlan Profile
                        GetApplication().IgmpGroups.Range(func(key, value interface{}) bool {
                                ig := value.(*IgmpGroup)
                                if ig.Mvlan == mvp.Mvlan {
                                        igd := ig.Devices[d.Name]
                                        ig.DelIgmpGroupDevice(igd)
                                        if ig.NumDevicesActive() == 0 {
                                                GetApplication().DelIgmpGroup(ig)
                                        }
                                }
                                return true
                        })

                        //Remove DS Igmp trap flow
                        err := mvp.RemoveIgmpDSFlowForMvp(d.Name)
                        if err != nil {
                                logger.Errorw(ctx, "DS IGMP Flow Del Failed", log.Fields{"Reason": err.Error(), "device": d.Name})
                        }
                }
        }
}

// ApplyIgmpDSFlowForMvp to apply Igmp DS flow for mvlan.
func (mvp *MvlanProfile) ApplyIgmpDSFlowForMvp(device string) error {
        va := GetApplication()
        dIntf, ok := va.DevicesDisc.Load(device)
        if !ok {
                return errors.New("Device Doesn't Exist")
        }
        d := dIntf.(*VoltDevice)
        mvlan := mvp.Mvlan

        flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
        if !ok || !flowAlreadyApplied {
                flows, err := mvp.BuildIgmpDSFlows(device)
                if err == nil {
                        err = cntlr.GetController().AddFlows(d.NniPort, device, flows)
                        if err != nil {
                                logger.Warnw(ctx, "Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
                                return err
                        }
                        d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)] = true
                        logger.Infow(ctx, "Updating voltDevice that IGMP DS flow as \"added\" for ",
                                log.Fields{"device": d.SerialNum, "mvlan": mvlan})
                } else {
                        logger.Errorw(ctx, "DS IGMP Flow Add Failed", log.Fields{"Reason": err.Error(), "Mvlan": mvlan})
                }
        }

        return nil
}

// RemoveIgmpDSFlowForMvp to remove Igmp DS flow for mvlan.
func (mvp *MvlanProfile) RemoveIgmpDSFlowForMvp(device string) error {

        va := GetApplication()
        mvlan := mvp.Mvlan

        dIntf, ok := va.DevicesDisc.Load(device)
        if !ok {
                return errors.New("Device Doesn't Exist")
        }
        d := dIntf.(*VoltDevice)
        /* No need of strict check during DS IGMP deletion
        flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
        if ok && flowAlreadyApplied
        */
        flows, err := mvp.BuildIgmpDSFlows(device)
        if err == nil {
                flows.ForceAction = true

                err = mvp.DelFlows(d, flows)
                if err != nil {
                        logger.Warnw(ctx, "De-Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
                        return err
                }
                d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)] = false
                logger.Infow(ctx, "Updating voltDevice that IGMP DS flow as \"removed\" for ",
                        log.Fields{"device": d.SerialNum, "mvlan": mvlan})
        } else {
                logger.Errorw(ctx, "DS IGMP Flow Del Failed", log.Fields{"Reason": err.Error()})
        }

        return nil
}

// BuildIgmpDSFlows to build Igmp DS flows for NNI port
func (mvp *MvlanProfile) BuildIgmpDSFlows(device string) (*of.VoltFlow, error) {
        dIntf, ok := GetApplication().DevicesDisc.Load(device)
        if !ok {
                return nil, errors.New("Device Doesn't Exist")
        }
        d := dIntf.(*VoltDevice)

        logger.Infow(ctx, "Building DS IGMP Flow for NNI port", log.Fields{"vs": d.NniPort, "Mvlan": mvp.Mvlan})
        flow := &of.VoltFlow{}
        flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
        subFlow := of.NewVoltSubFlow()
        subFlow.SetTableID(0)
        subFlow.SetMatchVlan(mvp.Mvlan)

        nniPort, err := GetApplication().GetNniPort(device)
        if err != nil {
                return nil, err
        }
        nniPortID, err1 := GetApplication().GetPortID(nniPort)
        if err1 != nil {
                return nil, errors.New("Unknown NNI outport")
        }
        subFlow.SetInPort(nniPortID)
        subFlow.SetIgmpMatch()
        subFlow.SetReportToController()
        subFlow.Cookie = uint64(nniPortID)<<32 | uint64(mvp.Mvlan)
        subFlow.Priority = of.IgmpFlowPriority

        flow.SubFlows[subFlow.Cookie] = subFlow
        logger.Infow(ctx, "Built DS IGMP flow", log.Fields{"cookie": subFlow.Cookie, "subflow": subFlow})
        return flow, nil
}

//updateStaticGroups - Generates static joins & leaves for newly added and removed static channels respectively
func (mvp *MvlanProfile) updateStaticGroups(deviceID string, added []net.IP, removed []net.IP) {

        //Update static group configs for all associated devices
        updateGroups := func(key interface{}, value interface{}) bool {
                d := value.(*VoltDevice)

                if mvp.DevicesList[d.SerialNum] == Nil {
                        logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": d, "Profile Device List": mvp.DevicesList})
                        return true
                }
                //TODO if mvp.IsChannelBasedGroup {
                mvp.ProcessStaticGroup(d.Name, added, true)
                mvp.ProcessStaticGroup(d.Name, removed, false)
                //}
                return true
        }

        if deviceID != "" {
                vd := GetApplication().GetDevice(deviceID)
                updateGroups(deviceID, vd)
        } else {
                GetApplication().DevicesDisc.Range(updateGroups)
        }
}

//updateDynamicGroups - Generates joins with updated sources for existing channels
func (mvp *MvlanProfile) updateDynamicGroups(deviceID string, added []net.IP, removed []net.IP) {

        //mvlan := mvp.Mvlan
        va := GetApplication()

        updateGroups := func(key interface{}, value interface{}) bool {
                d := value.(*VoltDevice)

                if mvp.DevicesList[d.SerialNum] == Nil {
                        logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": d, "Profile Device List": mvp.DevicesList})
                        return true
                }
                for _, groupAddr := range added {

                        _, gName := va.GetMvlanProfileForMcIP(mvp.Name, groupAddr)
                        grpKey := mvp.generateGroupKey(gName, groupAddr.String())
                        logger.Debugw(ctx, "IGMP Group", log.Fields{"Group": grpKey, "groupAddr": groupAddr})
                        if igIntf, ok := va.IgmpGroups.Load(grpKey); ok {
                                ig := igIntf.(*IgmpGroup)
                                if igd, ok := ig.getIgmpGroupDevice(d.Name); ok {
                                        if igcIntf, ok := igd.GroupChannels.Load(groupAddr.String()); ok {
                                                igc := igcIntf.(*IgmpGroupChannel)
                                                incl := false
                                                var ip []net.IP
                                                var groupModified = false
                                                if _, ok := mvp.Proxy[igc.GroupName]; ok {
                                                        if mvp.Proxy[igc.GroupName].Mode == common.Include {
                                                                incl = true
                                                        }
                                                        ip = mvp.Proxy[igc.GroupName].SourceList
                                                }
                                                for port, igp := range igc.NewReceivers {
                                                        // Process the include/exclude list which may end up modifying the group
                                                        if change, _ := igc.ProcessSources(port, ip, incl); change {
                                                                groupModified = true
                                                        }
                                                        igc.ProcessMode(port, incl)

                                                        if err := igp.WriteToDb(igc.Mvlan, igc.GroupAddr, igc.Device); err != nil {
                                                                logger.Errorw(ctx, "Igmp group port Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
                                                        }
                                                }
                                                // If the group is modified as this is the first receiver or due to include/exclude list modification
                                                // send a report to the upstream multicast servers
                                                if groupModified {
                                                        logger.Debug(ctx, "Group Modified and IGMP report sent to the upstream server")
                                                        igc.SendReport(false)
                                                }
                                                if err := igc.WriteToDb(); err != nil {
                                                        logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
                                                }
                                        }
                                }
                        }
                }

                return true
        }

        if deviceID != "" {
                vd := GetApplication().GetDevice(deviceID)
                updateGroups(deviceID, vd)
        } else {
                GetApplication().DevicesDisc.Range(updateGroups)
        }
}

//GroupsUpdated - Handles removing of Igmp Groups, flows & group table entries for
//channels removed as part of update
func (mvp *MvlanProfile) GroupsUpdated(deviceID string) {

        deleteChannelIfRemoved := func(key interface{}, value interface{}) bool {
                ig := value.(*IgmpGroup)

                if ig.Mvlan != mvp.Mvlan {
                        return true
                }
                grpName := ig.GroupName
                logger.Infow(ctx, "###Update Cycle", log.Fields{"IG": ig.GroupName, "Addr": ig.GroupAddr})
                //Check if group exists and remove the entire group object otherwise
                if currentChannels := mvp.Groups[grpName]; currentChannels != nil {

                        if mvp.IsChannelBasedGroup {
                                channelPresent := doesIPMatch(ig.GroupAddr, currentChannels.McIPs)
                                if channelPresent || mvp.isChannelStatic(ig.GroupAddr) {
                                        return true
                                }
                        } else {
                                allExistingChannels := ig.GetAllIgmpChannelForDevice(deviceID)
                                for channel := range allExistingChannels {
                                        channelIP := net.ParseIP(channel)
                                        channelPresent := mvp.IsChannelPresent(channelIP, currentChannels.McIPs, mvp.IsStaticGroup(ig.GroupName))
                                        if channelPresent {
                                                staticChannel := mvp.isChannelStatic(channelIP)
                                                logger.Infow(ctx, "###Channel Comparision", log.Fields{"staticChannel": staticChannel, "Group": mvp.IsStaticGroup(ig.GroupName), "Channel": channel})
                                                // Logic:
                                                // If channel is Static & existing Group is also static - No migration required
                                                // If channel is not Static & existing Group is also not static - No migration required

                                                // If channel is Static and existing Group is not static - Migrate (from dynamic to static)
                                                //    (Channel already part of dynamic, added to static)

                                                // If channel is not Static but existing Group is static - Migrate (from static to dynamic)
                                                //    (Channel removed from satic but part of dynamic)
                                                if (staticChannel != mvp.IsStaticGroup(ig.GroupName)) || (ig.IsGroupStatic != mvp.IsStaticGroup(ig.GroupName)) { // Equivalent of XOR
                                                        ig.HandleGroupMigration(deviceID, channelIP)
                                                } else {
                                                        if (ig.IsGroupStatic) && mvp.IsStaticGroup(ig.GroupName) {
                                                                if ig.GroupName != mvp.GetStaticGroupName(channelIP) {
                                                                        ig.HandleGroupMigration(deviceID, channelIP)
                                                                }
                                                        }
                                                        continue
                                                }
                                        } else {
                                                logger.Debugw(ctx, "Channel Removed", log.Fields{"Channel": channel, "Group": grpName})
                                                ig.DelIgmpChannel(deviceID, net.ParseIP(channel))
                                                if ig.NumDevicesActive() == 0 {
                                                        GetApplication().DelIgmpGroup(ig)
                                                }
                                        }
                                }
                                ig.IsGroupStatic = mvp.IsStaticGroup(ig.GroupName)
                                if err := ig.WriteToDb(); err != nil {
                                        logger.Errorw(ctx, "Igmp group Write to DB failed", log.Fields{"groupName": ig.GroupName})
                                }
                                return true
                        }
                }
                logger.Debugw(ctx, "Group Removed", log.Fields{"Channel": ig.GroupAddr, "Group": grpName, "ChannelBasedGroup": ig.IsChannelBasedGroup})
                ig.DelIgmpGroup()
                logger.Debugw(ctx, "Removed Igmp Group", log.Fields{"Channel": ig.GroupAddr, "Group": grpName})
                return true
        }
        GetApplication().IgmpGroups.Range(deleteChannelIfRemoved)
}

// IsChannelPresent to check if channel is present
func (mvp *MvlanProfile) IsChannelPresent(channelIP net.IP, groupChannelList []string, IsStaticGroup bool) bool {
        // Only in case of static group, migration need to be supported.
        // Dynamic to dynamic group migration not supported currently
        if doesIPMatch(channelIP, groupChannelList) || mvp.isChannelStatic(channelIP) {
                return true
        } else if IsStaticGroup {
                return (mvp.GetMvlanGroup(channelIP) != "")
        }

        return false
}


// GetMvlanGroup to get mvlan group
func (mvp *MvlanProfile) GetMvlanGroup(ip net.IP) string {
        //Check for Static Group First
        if mvp.containsStaticChannels() {
                grpName := mvp.GetStaticGroupName(ip)
                if grpName != "" {
                        return grpName
                }
        }

        for _, mvg := range mvp.Groups {
                if mvg.Wildcard {
                        return mvg.Name
                }
                if doesIPMatch(ip, mvg.McIPs) {
                        return mvg.Name
                }
        }
        return ""
}

// ProcessStaticGroup - Process Static Join/Leave Req for static channels
func (mvp *MvlanProfile) ProcessStaticGroup(device string, groupAddresses []net.IP, isJoin bool) {

        logger.Debugw(ctx, "Received Static Group Request", log.Fields{"Device": device, "Join": isJoin, "Group Address List": groupAddresses})

        mvlan := mvp.Mvlan
        va := GetApplication()

        //TODO - Handle bulk add of groupAddr
        for _, groupAddr := range groupAddresses {

                ig := mvp.GetStaticIgmpGroup(groupAddr)
                if isJoin {
                        vd := va.GetDevice(device)
                        igmpProf, _, _ := getIgmpProxyCfgAndIP(mvlan, vd.SerialNum)
                        ver := igmpProf.IgmpVerToServer

                        if ig == nil {
                                // First time group Creation: Create the IGMP group and then add the receiver to the group
                                logger.Infow(ctx, "Static IGMP Add received for new group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
                                if ig := GetApplication().AddIgmpGroup(mvp.Name, groupAddr, device); ig != nil {
                                        ig.IgmpGroupLock.Lock()
                                        ig.AddReceiver(device, StaticPort, groupAddr, nil, getVersion(ver),
                                                0, 0, 0xFF)
                                        ig.IgmpGroupLock.Unlock()
                                } else {
                                        logger.Warnw(ctx, "Static IGMP Group Creation Failed", log.Fields{"Addr": groupAddr})
                                }
                        } else {
                                //Converting existing dynamic group to static group
                                if !mvp.IsStaticGroup(ig.GroupName) {
                                        ig.updateGroupName(ig.GroupName)
                                }
                                // Update case: If the IGMP group is already created. just add the receiver
                                logger.Infow(ctx, "Static IGMP Add received for existing group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
                                ig.IgmpGroupLock.Lock()
                                ig.AddReceiver(device, StaticPort, groupAddr, nil, getVersion(ver),
                                        0, 0, 0xFF)
                                ig.IgmpGroupLock.Unlock()
                        }
                } else if ig != nil {
                        logger.Infow(ctx, "Static IGMP Del received for existing group", log.Fields{"Addr": groupAddr, "Port": StaticPort})

                        if ig.IsChannelBasedGroup {
                                grpName := mvp.GetMvlanGroup(ig.GroupAddr)
                                if grpName != "" {
                                        ig.IgmpGroupLock.Lock()
                                        ig.DelReceiver(device, StaticPort, groupAddr, nil, 0xFF)
                                        ig.IgmpGroupLock.Unlock()
                                        ig.updateGroupName(grpName)
                                } else {
                                        ig.DelIgmpGroup()
                                }
                        } else {
                                ig.IgmpGroupLock.Lock()
                                ig.DelReceiver(device, StaticPort, groupAddr, nil, 0xFF)
                                ig.IgmpGroupLock.Unlock()
                        }
                        if ig.NumDevicesActive() == 0 {
                                GetApplication().DelIgmpGroup(ig)
                        }
                } else {
                        logger.Warnw(ctx, "Static IGMP Del received for unknown group", log.Fields{"Addr": groupAddr})
                }
        }
}

//getStaticChannelDiff - return the static channel newly added and removed from existing static group
func (mvp *MvlanProfile) getStaticChannelDiff() (newlyAdded []net.IP, removed []net.IP, common []net.IP) {

        var commonChannels []net.IP
        newChannelList, _ := mvp.getAllStaticChannels()
        existingChannelList, _ := mvp.getAllOldGroupStaticChannels()
        if len(existingChannelList) == 0 {
                return newChannelList, []net.IP{}, []net.IP{}
        }
        for _, newChannel := range append([]net.IP{}, newChannelList...) {
                for _, existChannel := range append([]net.IP{}, existingChannelList...) {

                        //Remove common channels between existing and new list
                        // The remaining in the below slices give the results
                        // Remaining in newChannelList: Newly added
                        // Remaining in existingChannelList: Removed channels
                        if existChannel.Equal(newChannel) {
                                existingChannelList = removeIPFromList(existingChannelList, existChannel)
                                newChannelList = removeIPFromList(newChannelList, newChannel)
                                commonChannels = append(commonChannels, newChannel)
                                logger.Infow(ctx, "#############Channel: "+existChannel.String()+" New: "+newChannel.String(), log.Fields{"Added": newChannelList, "Removed": existingChannelList})
                                break
                        }
                }
        }
        return newChannelList, existingChannelList, commonChannels
}

//getGroupChannelDiff - return the channel newly added and removed from existing group
func (mvp *MvlanProfile) getGroupChannelDiff(newGroup *MvlanGroup, oldGroup *MvlanGroup) (newlyAdded []net.IP, removed []net.IP, common []net.IP) {

        var commonChannels []net.IP
        newChannelList, _ := newGroup.getAllChannels()
        existingChannelList, _ := oldGroup.getAllChannels()
        if len(existingChannelList) == 0 {
                return newChannelList, []net.IP{}, []net.IP{}
        }
        for _, newChannel := range append([]net.IP{}, newChannelList...) {
                for _, existChannel := range append([]net.IP{}, existingChannelList...) {

                        //Remove common channels between existing and new list
                        // The remaining in the below slices give the results
                        // Remaining in newChannelList: Newly added
                        // Remaining in existingChannelList: Removed channels
                        if existChannel.Equal(newChannel) {
                                existingChannelList = removeIPFromList(existingChannelList, existChannel)
                                newChannelList = removeIPFromList(newChannelList, newChannel)
                                commonChannels = append(commonChannels, newChannel)
                                logger.Infow(ctx, "#############Channel: "+existChannel.String()+" New: "+newChannel.String(), log.Fields{"Added": newChannelList, "Removed": existingChannelList})
                                break
                        }
                }
        }
        return newChannelList, existingChannelList, commonChannels
}

// UpdateProfile - Updates the group & member info w.r.t the mvlan profile for the given device
func (mvp *MvlanProfile) UpdateProfile(deviceID string) {
        logger.Infow(ctx, "Update Mvlan Profile task triggered", log.Fields{"Mvlan": mvp.Mvlan})
        var removedStaticChannels []net.IP
        addedStaticChannels := []net.IP{}
        /* Taking mvpLock to protect the mvp groups and proxy */
        mvp.mvpLock.RLock()
        defer mvp.mvpLock.RUnlock()

        serialNo := ""
        if deviceID != "" {
                if vd := GetApplication().GetDevice(deviceID); vd != nil {
                        serialNo = vd.SerialNum
                        if mvp.DevicesList[serialNo] != UpdateInProgress {
                                logger.Warnw(ctx, "Exiting Update Task since device not present in MvlanProfile", log.Fields{"Device": deviceID, "SerialNum": vd.SerialNum, "MvlanProfile": mvp})
                                return
                        }
                } else {
                        logger.Errorw(ctx, "Volt Device not found. Stopping Update Mvlan Profile processing for device", log.Fields{"SerialNo": deviceID, "MvlanProfile": mvp})
                        return
                }
        }

        //Update the groups based on static channels added & removed
        if mvp.containsStaticChannels() {
                addedStaticChannels, removedStaticChannels, _ = mvp.getStaticChannelDiff()
                logger.Debugw(ctx, "Update Task - Static Group Changes", log.Fields{"Added": addedStaticChannels, "Removed": removedStaticChannels})

                if len(addedStaticChannels) > 0 || len(removedStaticChannels) > 0 {
                        mvp.updateStaticGroups(deviceID, []net.IP{}, removedStaticChannels)
                }
        }
        mvp.GroupsUpdated(deviceID)
        if len(addedStaticChannels) > 0 {
                mvp.updateStaticGroups(deviceID, addedStaticChannels, []net.IP{})
        }

        /* Need to handle if SSM params are modified for groups */
        for key := range mvp.Groups {
                _, _, commonChannels := mvp.getGroupChannelDiff(mvp.Groups[key], mvp.oldGroups[key])
                if mvp.checkStaticGrpSSMProxyDiff(mvp.oldProxy[key], mvp.Proxy[key]) {
                        if mvp.Groups[key].IsStatic {
                                /* Static group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
                                mvp.updateStaticGroups(deviceID, commonChannels, []net.IP{})
                        } else {
                                /* Dynamic group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
                                mvp.updateDynamicGroups(deviceID, commonChannels, []net.IP{})
                        }
                }
        }

        mvp.SetUpdateStatus(serialNo, NoOp)

        if deviceID == "" || !mvp.isUpdateInProgress() {
                mvp.oldGroups = nil
        }
        if err := mvp.WriteToDb(); err != nil {
                logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
        }
        logger.Debugw(ctx, "Updated MVLAN Profile", log.Fields{"VLAN": mvp.Mvlan, "Name": mvp.Name, "Grp IPs": mvp.Groups})
}

//checkStaticGrpSSMProxyDiff- return true if the proxy of oldGroup is modified in newGroup
func (mvp *MvlanProfile) checkStaticGrpSSMProxyDiff(oldProxy *MCGroupProxy, newProxy *MCGroupProxy) bool {

        if oldProxy == nil && newProxy == nil {
                return false
        }
        if (oldProxy == nil && newProxy != nil) ||
                (oldProxy != nil && newProxy == nil) {
                return true
        }

        if oldProxy.Mode != newProxy.Mode {
                return true
        }

        oldSrcLst := oldProxy.SourceList
        newSrcLst := newProxy.SourceList
        oLen := len(oldSrcLst)
        nLen := len(newSrcLst)
        if oLen != nLen {
                return true
        }

        visited := make([]bool, nLen)

        /* check if any new IPs added in the src list, return true if present */
        for i := 0; i < nLen; i++ {
                found := false
                element := newSrcLst[i]
                for j := 0; j < oLen; j++ {
                        if visited[j] {
                                continue
                        }
                        if element.Equal(oldSrcLst[j]) {
                                visited[j] = true
                                found = true
                                break
                        }
                }
                if !found {
                        return true
                }
        }

        visited = make([]bool, nLen)
        /* check if any IPs removed from existing  src list, return true if removed */
        for i := 0; i < oLen; i++ {
                found := false
                element := oldSrcLst[i]
                for j := 0; j < nLen; j++ {
                        if visited[j] {
                                continue
                        }
                        if element.Equal(newSrcLst[j]) {
                                visited[j] = true
                                found = true
                                break
                        }
                }
                if !found {
                        return true
                }
        }
        return false
}


//UpdateActiveChannelSubscriberAlarm - Updates the Active Channel Subscriber Alarm
func (mvp *MvlanProfile) UpdateActiveChannelSubscriberAlarm() {
        va := GetApplication()
        logger.Debugw(ctx, "Update of Active Channel Subscriber Alarm", log.Fields{"Mvlan": mvp.Mvlan})
        for srNo := range mvp.DevicesList {
                d := va.GetDeviceBySerialNo(srNo)
                if d == nil {
                        logger.Warnw(ctx, "Device info not found", log.Fields{"Device_SrNo": srNo, "Mvlan": mvp.Mvlan})
                        return
                }
                d.Ports.Range(func(key, value interface{}) bool {
                        //port := key.(string)
                        vp := value.(*VoltPort)
                        if vp.Type != VoltPortTypeAccess {
                                return true
                        }
                        if mvp.MaxActiveChannels > vp.ActiveChannels && vp.ChannelPerSubAlarmRaised {
                                serviceName := GetMcastServiceForSubAlarm(vp, mvp)
                                logger.Debugw(ctx, "Clearing-SendActiveChannelPerSubscriberAlarm-due-to-update", log.Fields{"ActiveChannels": vp.ActiveChannels, "ServiceName": serviceName})
                                vp.ChannelPerSubAlarmRaised = false
                        } else if mvp.MaxActiveChannels < vp.ActiveChannels && !vp.ChannelPerSubAlarmRaised {
                                /* When the max active channel count is reduced via update, we raise an alarm.
                                   But the previous excess channels still exist until a leave or expiry */
                                serviceName := GetMcastServiceForSubAlarm(vp, mvp)
                                logger.Debugw(ctx, "Raising-SendActiveChannelPerSubscriberAlarm-due-to-update", log.Fields{"ActiveChannels": vp.ActiveChannels, "ServiceName": serviceName})
                                vp.ChannelPerSubAlarmRaised = true
                        }
                        return true
                })
        }
}

//TriggerAssociatedFlowDelete - Re-trigger delete for pending delete flows
func (mvp *MvlanProfile) TriggerAssociatedFlowDelete(device string) bool {
        mvp.mvpFlowLock.Lock()

        cookieList := []uint64{}
        flowMap := mvp.PendingDeleteFlow[device]

        for cookie := range flowMap {
                cookieList = append(cookieList, convertToUInt64(cookie))
        }
        mvp.mvpFlowLock.Unlock()

        if len(cookieList) == 0 {
                return false
        }

        for _, cookie := range cookieList {
                if vd := GetApplication().GetDevice(device); vd != nil {
                        flow := &of.VoltFlow{}
                        flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
                        subFlow := of.NewVoltSubFlow()
                        subFlow.Cookie = cookie
                        flow.SubFlows[cookie] = subFlow
                        logger.Infow(ctx, "Retriggering Vnet Delete Flow", log.Fields{"Device": device, "Mvlan": mvp.Mvlan.String(), "Cookie": cookie})
                        err := mvp.DelFlows(vd, flow)
                        if err != nil {
                                logger.Warnw(ctx, "De-Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
                        }
                }
        }
        return true
}

// JsonMarshal wrapper function for json Marshal MvlanProfile
func (mvp *MvlanProfile) JsonMarshal() ([]byte, error) {
        return json.Marshal(MvlanProfile{
                Name:                mvp.Name,
                Mvlan:               mvp.Mvlan,
                PonVlan:             mvp.PonVlan,
                Groups:              mvp.Groups,
                Proxy:               mvp.Proxy,
                Version:             mvp.Version,
                IsPonVlanPresent:    mvp.IsPonVlanPresent,
                IsChannelBasedGroup: mvp.IsChannelBasedGroup,
                DevicesList:         mvp.DevicesList,
                MaxActiveChannels:   mvp.MaxActiveChannels,
                PendingDeleteFlow:   mvp.PendingDeleteFlow,
                DeleteInProgress:    mvp.DeleteInProgress,
                IgmpServVersion:     mvp.IgmpServVersion,
        })
}

// removeIPFromList to remove ip from the list
func removeIPFromList(s []net.IP, value net.IP) []net.IP {
        i := 0
        for i = 0; i < len(s); i++ {
                if s[i].Equal(value) {
                        break
                }
        }
        if i != len(s) {
                //It means value is found in the slice
                return append(s[0:i], s[i+1:]...)
        }
        return s
}

// doesIPMatch to check if ip match with any ip from the list
func doesIPMatch(ip net.IP, ipsOrRange []string) bool {
        for _, ipOrRange := range ipsOrRange {
                if strings.Contains(ipOrRange, "-") {
                        var splits = strings.Split(ipOrRange, "-")
                        ipStart := util.IP2LongConv(net.ParseIP(splits[0]))
                        ipEnd := util.IP2LongConv(net.ParseIP(splits[1]))
                        if ipEnd < ipStart {
                                return false
                        }
                        ipInt := util.IP2LongConv(ip)
                        if ipInt >= ipStart && ipInt <= ipEnd {
                                return true
                        }
                } else if ip.Equal(net.ParseIP(ipOrRange)) {
                        return true
                }
        }
        return false
}

// IgmpProfile structure
type IgmpProfile struct {
        ProfileID          string
        UnsolicitedTimeOut uint32 //In seconds
        MaxResp            uint32
        KeepAliveInterval  uint32
        KeepAliveCount     uint32
        LastQueryInterval  uint32
        LastQueryCount     uint32
        FastLeave          bool
        PeriodicQuery      bool
        IgmpCos            uint8
        WithRAUpLink       bool
        WithRADownLink     bool
        IgmpVerToServer    string
        IgmpSourceIP       net.IP
        Version            string
}

func newIgmpProfile(igmpProfileConfig *common.IGMPConfig) *IgmpProfile {
        var igmpProfile IgmpProfile
        igmpProfile.ProfileID = igmpProfileConfig.ProfileID
        igmpProfile.UnsolicitedTimeOut = uint32(igmpProfileConfig.UnsolicitedTimeOut)
        igmpProfile.MaxResp = uint32(igmpProfileConfig.MaxResp)

        keepAliveInterval := uint32(igmpProfileConfig.KeepAliveInterval)

        //KeepAliveInterval should have a min of 10 seconds
        if keepAliveInterval < MinKeepAliveInterval {
                keepAliveInterval = MinKeepAliveInterval
                logger.Infow(ctx, "Auto adjust keepAliveInterval - Value < 10", log.Fields{"Received": igmpProfileConfig.KeepAliveInterval, "Configured": keepAliveInterval})
        }
        igmpProfile.KeepAliveInterval = keepAliveInterval

        igmpProfile.KeepAliveCount = uint32(igmpProfileConfig.KeepAliveCount)
        igmpProfile.LastQueryInterval = uint32(igmpProfileConfig.LastQueryInterval)
        igmpProfile.LastQueryCount = uint32(igmpProfileConfig.LastQueryCount)
        igmpProfile.FastLeave = *igmpProfileConfig.FastLeave
        igmpProfile.PeriodicQuery = *igmpProfileConfig.PeriodicQuery
        igmpProfile.IgmpCos = uint8(igmpProfileConfig.IgmpCos)
        igmpProfile.WithRAUpLink = *igmpProfileConfig.WithRAUpLink
        igmpProfile.WithRADownLink = *igmpProfileConfig.WithRADownLink

        if igmpProfileConfig.IgmpVerToServer == "2" || igmpProfileConfig.IgmpVerToServer == "v2" {
                igmpProfile.IgmpVerToServer = "2"
        } else {
                igmpProfile.IgmpVerToServer = "3"
        }
        igmpProfile.IgmpSourceIP = net.ParseIP(igmpProfileConfig.IgmpSourceIP)

        return &igmpProfile
}

// newDefaultIgmpProfile Igmp profiles with default values
func newDefaultIgmpProfile() *IgmpProfile {
        return &IgmpProfile{
                ProfileID:          DefaultIgmpProfID,
                UnsolicitedTimeOut: 60,
                MaxResp:            10, // seconds
                KeepAliveInterval:  60, // seconds
                KeepAliveCount:     3,  // TODO - May not be needed
                LastQueryInterval:  0,  // TODO - May not be needed
                LastQueryCount:     0,  // TODO - May not be needed
                FastLeave:          true,
                PeriodicQuery:      false, // TODO - May not be needed
                IgmpCos:            7,     //p-bit value included in the IGMP packet
                WithRAUpLink:       false, // TODO - May not be needed
                WithRADownLink:     false, // TODO - May not be needed
                IgmpVerToServer:    "3",
                IgmpSourceIP:       net.ParseIP("172.27.0.1"), // This will be replaced by configuration
        }
}

// WriteToDb is utility to write Igmp Config Info to database
func (igmpProfile *IgmpProfile) WriteToDb() error {
        igmpProfile.Version = database.PresentVersionMap[database.IgmpProfPath]
        b, err := json.Marshal(igmpProfile)
        if err != nil {
                return err
        }
        if err1 := db.PutIgmpProfile(igmpProfile.ProfileID, string(b)); err1 != nil {
                return err1
        }
        return nil
}
