/*
 * Copyright 2018-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 igmp

import (
	"encoding/binary"
	"encoding/hex"
	"errors"
	"github.com/opencord/bbsim/internal/bbsim/packetHandlers"
	"net"
	"time"

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

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

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

	data := &openolt.Indication_PktInd{
		PktInd: &openolt.PacketIndication{
			IntfType:  "pon",
			IntfId:    ponPortId,
			GemportId: gemPortId,
			Pkt:       pkt,
			PortNo:    portNo,
		},
	}
	//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,
			"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,
	gemPortId uint32, macAddress net.HardwareAddr, cTag int, pbit uint8, stream bbsim.Stream) error {

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

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

	data := &openolt.Indication_PktInd{
		PktInd: &openolt.PacketIndication{
			IntfType:  "pon",
			IntfId:    ponPortId,
			GemportId: gemPortId,
			Pkt:       pkt,
			PortNo:    portNo,
		},
	}
	//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,
			"err":          err,
		}).Errorf("Fail to send IGMP PktInd indication")
		return err
	}

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

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

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

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

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

	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": pkt.Data(),
	}).Trace("IGMP packet")

	igmp := igmpLayer.(*layers.IGMPv1or2)

	if igmp.Type == layers.IGMPMembershipQuery {
		_ = SendIGMPMembershipReportV2(ponPortId, onuId, serialNumber, portNo, gemPortId, macAddress, cTag, pbit, stream)
	}

	return nil
}

func createIGMPV3MembershipReportPacket() *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
	}

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

	igmpDefault := &IGMP{
		Type:                    layers.IGMPMembershipReportV3, //IGMPV3 Membership Report
		MaxResponseTime:         time.Duration(1),
		Checksum:                0,
		GroupAddress:            net.IPv4(224, 0, 0, 22),
		SupressRouterProcessing: false,
		RobustnessValue:         0,
		IntervalTime:            time.Duration(1),
		SourceAddresses:         []net.IP{net.IPv4(224, 0, 0, 24)},
		NumberOfGroupRecords:    2,
		NumberOfSources:         1,
		GroupRecords:            []IGMPv3GroupRecord{groupRecord1, groupRecord2},
		Version:                 3,
	}

	return igmpDefault
}

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

func createIGMPV2LeaveRequestPacket() *IGMP {
	return &IGMP{
		Type:            layers.IGMPLeaveGroup, //IGMPV2 Leave Group
		MaxResponseTime: time.Duration(1),
		Checksum:        0,
		GroupAddress:    net.IPv4(224, 0, 0, 22),
		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,
	}

	ipLayer := &layers.IPv4{
		Version:  4,
		TOS:      0x10,
		Id:       0,
		TTL:      128,
		SrcIP:    []byte{0, 0, 0, 0},
		DstIP:    []byte{224, 0, 0, 22},
		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            []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 }
