/*
 * Copyright 2018-2024 Open Networking Foundation (ONF) and the ONF Contributors
 * 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 igmp

import (
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"net"
	"strconv"
	"time"

	"github.com/opencord/bbsim/internal/bbsim/packetHandlers"

	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	bbsim "github.com/opencord/bbsim/internal/bbsim/types"
	"github.com/opencord/voltha-protos/v5/go/openolt"
	log "github.com/sirupsen/logrus"
)

func SendIGMPLeaveGroupV2(ponPortId uint32, onuId uint32, serialNumber string, portNo uint32, uniId uint32,
	gemPortId uint32, macAddress net.HardwareAddr, cTag int, pbit uint8, stream bbsim.Stream, groupAddress string) error {
	log.WithFields(log.Fields{
		"OnuId":        onuId,
		"SerialNumber": serialNumber,
		"PortNo":       portNo,
		"GroupAddress": groupAddress,
	}).Debugf("Entered SendIGMPLeaveGroupV2")
	igmp := createIGMPV2LeaveRequestPacket(groupAddress)
	pkt, err := serializeIgmpPacket(ponPortId, onuId, cTag, macAddress, pbit, igmp)

	if err != nil {
		log.WithFields(log.Fields{
			"OnuId":        onuId,
			"IntfId":       ponPortId,
			"SerialNumber": serialNumber,
			"GroupAddress": groupAddress,
		}).Errorf("Seriliazation of igmp packet failed :  %s", err)
		return err
	}

	// For IGMP testing, if voltha is not connected we do not have
	// gemPortId, so set a unique gemPortId per ONU
	if gemPortId == 0 {
		gid, _ := strconv.ParseUint(fmt.Sprintf("%d%d", ponPortId, onuId), 10, 32)
		gemPortId = uint32(gid)
	}

	data := &openolt.Indication_PktInd{
		PktInd: &openolt.PacketIndication{
			IntfType:  "pon",
			IntfId:    ponPortId,
			GemportId: gemPortId,
			Pkt:       pkt,
			PortNo:    portNo,
			OnuId:     onuId,
			UniId:     uniId,
		},
	}
	//Sending IGMP packets
	if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
		log.WithFields(log.Fields{
			"OnuId":        onuId,
			"SerialNumber": serialNumber,
			"PortNo":       portNo,
			"IntfId":       ponPortId,
			"GroupAddress": groupAddress,
			"err":          err,
		}).Error("Fail to send IGMP PktInd indication for ONU")
		return err
	}
	return nil
}

func SendIGMPMembershipReportV2(ponPortId uint32, onuId uint32, serialNumber string, portNo uint32, uniId uint32,
	gemPortId uint32, macAddress net.HardwareAddr, cTag int, pbit uint8, stream bbsim.Stream, groupAddress string) error {

	igmp := createIGMPV2MembershipReportPacket(groupAddress)
	pkt, err := serializeIgmpPacket(ponPortId, onuId, cTag, macAddress, pbit, igmp)

	if err != nil {
		log.WithFields(log.Fields{
			"OnuId":        onuId,
			"IntfId":       ponPortId,
			"SerialNumber": serialNumber,
			"GroupAddress": groupAddress,
		}).Errorf("Seriliazation of igmp packet failed :  %s", err)
		return err
	}

	// For IGMP testing, if voltha is not connected we do not have
	// gemPortId, so set a unique gemPortId per ONU
	if gemPortId == 0 {
		gid, _ := strconv.ParseUint(fmt.Sprintf("%d%d", ponPortId, onuId), 10, 32)
		gemPortId = uint32(gid)
	}

	data := &openolt.Indication_PktInd{
		PktInd: &openolt.PacketIndication{
			IntfType:  "pon",
			IntfId:    ponPortId,
			GemportId: gemPortId,
			Pkt:       pkt,
			PortNo:    portNo,
			OnuId:     onuId,
			UniId:     uniId,
		},
	}
	//Sending IGMP packets
	if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
		log.WithFields(log.Fields{
			"OnuId":        onuId,
			"SerialNumber": serialNumber,
			"PortNo":       portNo,
			"IntfId":       ponPortId,
			"GroupAddress": groupAddress,
			"err":          err,
		}).Errorf("Fail to send IGMP PktInd indication")
		return err
	}

	log.WithFields(log.Fields{
		"OnuId":        onuId,
		"SerialNumber": serialNumber,
		"PortNo":       portNo,
		"GroupAddress": groupAddress,
	}).Debugf("Sent SendIGMPMembershipReportV2")
	return nil
}

func SendIGMPMembershipReportV3(ponPortId uint32, onuId uint32, serialNumber string, portNo uint32, uniId uint32,
	gemPortId uint32, macAddress net.HardwareAddr, cTag int, pbit uint8, stream bbsim.Stream, groupAddress string) error {

	log.WithFields(log.Fields{
		"OnuId":        onuId,
		"SerialNumber": serialNumber,
		"PortNo":       portNo,
		"GroupAddress": groupAddress,
	}).Debugf("Entered SendIGMPMembershipReportV3")
	igmp := createIGMPV3MembershipReportPacket(groupAddress)
	pkt, err := serializeIgmpPacket(ponPortId, onuId, cTag, macAddress, pbit, igmp)

	if err != nil {
		log.WithFields(log.Fields{
			"OnuId":        onuId,
			"IntfId":       ponPortId,
			"SerialNumber": serialNumber,
			"GroupAddress": groupAddress,
		}).Errorf("Seriliazation of igmp packet failed :  %s", err)
		return err
	}

	// For IGMP testing, if voltha is not connected we do not have
	// gemPortId, so set a unique gemPortId per ONU
	if gemPortId == 0 {
		gid, _ := strconv.ParseUint(fmt.Sprintf("%d%d", ponPortId, onuId), 10, 32)
		gemPortId = uint32(gid)
	}

	data := &openolt.Indication_PktInd{
		PktInd: &openolt.PacketIndication{
			IntfType:  "pon",
			IntfId:    ponPortId,
			GemportId: gemPortId,
			Pkt:       pkt,
			PortNo:    portNo,
			OnuId:     onuId,
			UniId:     uniId,
		},
	}
	//Sending IGMP packets
	if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
		log.WithFields(log.Fields{
			"OnuId":        onuId,
			"IntfId":       ponPortId,
			"SerialNumber": serialNumber,
			"GroupAddress": groupAddress,
			"err":          err,
		}).Errorf("Fail to send IGMP PktInd indication")
		return err
	}
	return nil
}

func HandleNextPacket(ponPortId uint32, onuId uint32, serialNumber string, portNo uint32, uniId uint32,
	gemPortId uint32, macAddress net.HardwareAddr, pkt gopacket.Packet, cTag int, pbit uint8, groupAddresses map[string]int, stream bbsim.Stream) error {

	dot1qLayer := pkt.Layer(layers.LayerTypeDot1Q)
	if dot1qLayer == nil {
		log.WithFields(log.Fields{"Pkt": hex.EncodeToString(pkt.Data())}).Warnf("packet-is-not-tagged")
		return errors.New("packet-is-not-tagged")
	}
	dot1q := dot1qLayer.(*layers.Dot1Q)

	igmpLayer := pkt.Layer(layers.LayerTypeIGMP)
	if igmpLayer == nil {
		log.WithFields(log.Fields{
			"OnuId":        onuId,
			"SerialNumber": serialNumber,
			"PortNo":       portNo,
			"Pkt":          hex.EncodeToString(pkt.Data()),
		}).Error("This is not an IGMP packet")
		return errors.New("packet-is-not-igmp")
	}

	log.WithFields(log.Fields{
		"Pkt": hex.EncodeToString(pkt.Data()),
	}).Trace("IGMP packet")

	var igmp *IGMP
	igmpv1or2, ok := igmpLayer.(*layers.IGMPv1or2)
	if ok {
		igmp = &IGMP{
			Type:            igmpv1or2.Type,
			MaxResponseTime: igmpv1or2.MaxResponseTime,
			Checksum:        igmpv1or2.Checksum,
			GroupAddress:    igmpv1or2.GroupAddress,
			Version:         igmpv1or2.Version,
		}
	} else {
		igmpv3, ok := igmpLayer.(*layers.IGMP)
		if ok {
			igmp = &IGMP{
				Type:                    igmpv3.Type,
				MaxResponseTime:         igmpv3.MaxResponseTime,
				Checksum:                igmpv3.Checksum,
				GroupAddress:            igmpv3.GroupAddress,
				SupressRouterProcessing: igmpv3.SupressRouterProcessing,
				RobustnessValue:         igmpv3.RobustnessValue,
				IntervalTime:            igmpv3.IntervalTime,
				SourceAddresses:         igmpv3.SourceAddresses,
				NumberOfGroupRecords:    igmpv3.NumberOfGroupRecords,
				NumberOfSources:         igmpv3.NumberOfSources,
				GroupRecords:            igmpv3.GroupRecords,
				Version:                 igmpv3.Version,
			}
		} else {
			log.Warnf("could-not-parse-igmp-packet")
		}
	}

	if igmp.Type == layers.IGMPMembershipQuery {
		// Send response to queries only if joined to a group
		for groupAddr, vlan := range groupAddresses {
			if vlan == int(dot1q.VLANIdentifier) {
				_ = SendIGMPMembershipReportV2(ponPortId, onuId, serialNumber, portNo, uniId, gemPortId, macAddress,
					vlan, pbit, stream, groupAddr)
			}
		}
		if groupAddresses == nil {
			log.WithFields(log.Fields{
				"OnuId":        onuId,
				"SerialNumber": serialNumber,
				"PortNo":       portNo,
				"Pkt":          hex.EncodeToString(pkt.Data()),
			}).Trace("no-active-channels")
		}
	}

	return nil
}

func createIGMPV3MembershipReportPacket(groupAddress string) *IGMP {

	// groupRecord1 := IGMPv3GroupRecord{
	// 	Type:             IGMPv3GroupRecordType(IGMPIsIn),
	// 	AuxDataLen:       0, // this should always be 0 as per IGMPv3 spec.
	// 	NumberOfSources:  3,
	// 	MulticastAddress: net.IPv4(224, 0, 0, 22),
	// 	SourceAddresses:  []net.IP{net.IPv4(15, 14, 20, 24), net.IPv4(15, 14, 20, 26), net.IPv4(15, 14, 20, 25)},
	// 	AuxData:          0, // NOT USED
	// }

	// Keeping this as an example
	// groupRecord1 := IGMPv3GroupRecord{
	// 	Type:             IGMPv3GroupRecordType(IGMPIsIn),
	// 	AuxDataLen:       0, // this should always be 0 as per IGMPv3 spec.
	// 	NumberOfSources:  3,
	// 	MulticastAddress: net.IPv4(224, 0, 0, 22),
	// 	SourceAddresses:  []net.IP{net.IPv4(15, 14, 20, 24), net.IPv4(15, 14, 20, 26), net.IPv4(15, 14, 20, 25)},
	// 	AuxData:          0, // NOT USED
	// }

	groupRecord := layers.IGMPv3GroupRecord{
		Type:             layers.IGMPv3GroupRecordType(IGMPIsEx),
		AuxDataLen:       0, // this should always be 0 as per IGMPv3 spec.
		NumberOfSources:  0,
		MulticastAddress: net.ParseIP(groupAddress),
		AuxData:          0, // NOT USED
	}

	igmpDefault := &IGMP{
		Type:                    layers.IGMPMembershipReportV3, //IGMPV3 Membership Report
		MaxResponseTime:         time.Duration(1),
		Checksum:                0,
		GroupAddress:            net.ParseIP(groupAddress),
		SupressRouterProcessing: false,
		RobustnessValue:         0,
		IntervalTime:            time.Duration(1),
		NumberOfGroupRecords:    1,
		NumberOfSources:         0,
		GroupRecords:            []layers.IGMPv3GroupRecord{groupRecord},
		Version:                 3,
	}

	return igmpDefault
}

func createIGMPV2MembershipReportPacket(groupAddress string) *IGMP {
	return &IGMP{
		Type:         layers.IGMPMembershipReportV2, //IGMPV2 Membership Report
		Checksum:     0,
		GroupAddress: net.ParseIP(groupAddress),
		Version:      2,
	}
}

func createIGMPV2LeaveRequestPacket(groupAddress string) *IGMP {
	return &IGMP{
		Type:            layers.IGMPLeaveGroup, //IGMPV2 Leave Group
		MaxResponseTime: time.Duration(1),
		Checksum:        0,
		GroupAddress:    net.ParseIP(groupAddress),
		Version:         2,
	}
}

func serializeIgmpPacket(intfId uint32, onuId uint32, cTag int, srcMac net.HardwareAddr, pbit uint8, igmp *IGMP) ([]byte, error) {
	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{
		ComputeChecksums: true,
		FixLengths:       true,
	}

	ethernetLayer := &layers.Ethernet{
		SrcMAC:       srcMac,
		DstMAC:       net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
		EthernetType: layers.EthernetTypeIPv4,
	}

	destinationIP := igmp.GroupAddress
	if igmp.Version == 3 && igmp.Type == layers.IGMPMembershipReportV3 {
		//All IGMPv3-capable multicast routers
		destinationIP = net.ParseIP("224.0.0.22")
	}

	ipLayer := &layers.IPv4{
		Version:  4,
		TOS:      0x10,
		Id:       0,
		TTL:      128,
		SrcIP:    []byte{0, 0, 0, 0},
		DstIP:    destinationIP,
		Protocol: layers.IPProtocolIGMP,
		Options:  []layers.IPv4Option{{OptionType: 148, OptionLength: 4, OptionData: make([]byte, 0)}}, //Adding router alert option
	}

	if err := gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, igmp); err != nil {
		return nil, err
	}

	untaggedPkt := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default)
	taggedPkt, err := packetHandlers.PushSingleTag(cTag, untaggedPkt, pbit)

	if err != nil {
		log.Error("TagPacket")
		return nil, err
	}

	return taggedPkt.Data(), nil
}

//-----------------------------------------***********************---------------------------------

type IGMP struct {
	layers.BaseLayer
	Type                    layers.IGMPType
	MaxResponseTime         time.Duration
	Checksum                uint16
	GroupAddress            net.IP
	SupressRouterProcessing bool
	RobustnessValue         uint8
	IntervalTime            time.Duration
	SourceAddresses         []net.IP
	NumberOfGroupRecords    uint16
	NumberOfSources         uint16
	GroupRecords            []layers.IGMPv3GroupRecord
	Version                 uint8 // IGMP protocol version
}

// IGMPv3GroupRecord stores individual group records for a V3 Membership Report message.
type IGMPv3GroupRecord struct {
	Type             IGMPv3GroupRecordType
	AuxDataLen       uint8 // this should always be 0 as per IGMPv3 spec.
	NumberOfSources  uint16
	MulticastAddress net.IP
	SourceAddresses  []net.IP
	AuxData          uint32 // NOT USED
}

type IGMPv3GroupRecordType uint8

const (
	IGMPIsIn  IGMPv3GroupRecordType = 0x01 // Type MODE_IS_INCLUDE, source addresses x
	IGMPIsEx  IGMPv3GroupRecordType = 0x02 // Type MODE_IS_EXCLUDE, source addresses x
	IGMPToIn  IGMPv3GroupRecordType = 0x03 // Type CHANGE_TO_INCLUDE_MODE, source addresses x
	IGMPToEx  IGMPv3GroupRecordType = 0x04 // Type CHANGE_TO_EXCLUDE_MODE, source addresses x
	IGMPAllow IGMPv3GroupRecordType = 0x05 // Type ALLOW_NEW_SOURCES, source addresses x
	IGMPBlock IGMPv3GroupRecordType = 0x06 // Type BLOCK_OLD_SOURCES, source addresses x
)

func (i IGMPv3GroupRecordType) String() string {
	switch i {
	case IGMPIsIn:
		return "MODE_IS_INCLUDE"
	case IGMPIsEx:
		return "MODE_IS_EXCLUDE"
	case IGMPToIn:
		return "CHANGE_TO_INCLUDE_MODE"
	case IGMPToEx:
		return "CHANGE_TO_EXCLUDE_MODE"
	case IGMPAllow:
		return "ALLOW_NEW_SOURCES"
	case IGMPBlock:
		return "BLOCK_OLD_SOURCES"
	default:
		return ""
	}
}

// SerializeTo writes the serialized form of this layer into the
// SerializationBuffer, implementing gopacket.SerializableLayer.
// See the docs for gopacket.SerializableLayer for more info.
func (igmp *IGMP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
	data, err := b.PrependBytes(8915)
	if err != nil {
		return err
	}
	if igmp.Version == 2 {
		data[0] = byte(igmp.Type)
		data[1] = byte(igmp.MaxResponseTime)
		data[2] = 0
		data[3] = 0
		copy(data[4:8], igmp.GroupAddress.To4())
		if opts.ComputeChecksums {
			igmp.Checksum = tcpipChecksum(data, 0)
			binary.BigEndian.PutUint16(data[2:4], igmp.Checksum)
		}
	} else if igmp.Version == 3 {

		data[0] = byte(igmp.Type)
		data[1] = 0
		data[2] = 0
		data[3] = 0
		data[4] = 0
		data[5] = 0
		binary.BigEndian.PutUint16(data[6:8], igmp.NumberOfGroupRecords)
		j := 8
		for i := uint16(0); i < igmp.NumberOfGroupRecords; i++ {
			data[j] = byte(igmp.GroupRecords[i].Type)
			data[j+1] = byte(0)
			binary.BigEndian.PutUint16(data[j+2:j+4], igmp.GroupRecords[i].NumberOfSources)
			copy(data[j+4:j+8], igmp.GroupRecords[i].MulticastAddress.To4())
			j = j + 8
			for m := uint16(0); m < igmp.GroupRecords[i].NumberOfSources; m++ {
				copy(data[j:(j+4)], igmp.GroupRecords[i].SourceAddresses[m].To4())
				j = j + 4
			}
		}
		if opts.ComputeChecksums {
			igmp.Checksum = tcpipChecksum(data, 0)
			binary.BigEndian.PutUint16(data[2:4], igmp.Checksum)
		}
	}
	return nil
}

// Calculate the TCP/IP checksum defined in rfc1071.  The passed-in csum is any
// initial checksum data that's already been computed.
func tcpipChecksum(data []byte, csum uint32) uint16 {
	// to handle odd lengths, we loop to length - 1, incrementing by 2, then
	// handle the last byte specifically by checking against the original
	// length.
	length := len(data) - 1
	for i := 0; i < length; i += 2 {
		// For our test packet, doing this manually is about 25% faster
		// (740 ns vs. 1000ns) than doing it by calling binary.BigEndian.Uint16.
		csum += uint32(data[i]) << 8
		csum += uint32(data[i+1])
	}
	if len(data)%2 == 1 {
		csum += uint32(data[length]) << 8
	}
	for csum > 0xffff {
		csum = (csum >> 16) + (csum & 0xffff)
	}
	return ^uint16(csum)
}

func (i *IGMP) LayerType() gopacket.LayerType { return layers.LayerTypeIGMP }
func (i *IGMP) LayerContents() []byte         { return i.Contents }
func (i *IGMP) LayerPayload() []byte          { return i.Payload }
