/*
 * 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 dhcp

import (
	"context"
	"encoding/hex"
	"errors"
	"fmt"
	"net"
	"reflect"
	"strconv"

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

var dhcpLogger = log.WithFields(log.Fields{
	"module": "DHCP",
})

var defaultParamsRequestList = []layers.DHCPOpt{
	layers.DHCPOptSubnetMask,
	layers.DHCPOptBroadcastAddr,
	layers.DHCPOptTimeOffset,
	layers.DHCPOptRouter,
	layers.DHCPOptDomainName,
	layers.DHCPOptDNS,
	layers.DHCPOptDomainSearch,
	layers.DHCPOptHostname,
	layers.DHCPOptNetBIOSTCPNS,
	layers.DHCPOptNetBIOSTCPScope,
	layers.DHCPOptInterfaceMTU,
	layers.DHCPOptClasslessStaticRoute,
	layers.DHCPOptNTPServers,
}

func createDefaultDHCPReq(oltId int, intfId uint32, onuId uint32, mac net.HardwareAddr) layers.DHCPv4 {
	// NOTE we want to generate a unique XID, the easiest way is to concat the PON ID and the ONU ID
	// we increment them by one otherwise:
	// - OLT: 0 PON: 0 ONU: 62 = 062 -> 62
	// - OLT: 0 PON: 6 ONU: 2 = 62 -> 62
	xid, err := strconv.Atoi(fmt.Sprintf("%d%d%d", oltId+1, intfId+1, onuId+1))
	if err != nil {
		log.Fatal("Can't generate unique XID for ONU")
	}

	return layers.DHCPv4{
		Operation:    layers.DHCPOpRequest,
		HardwareType: layers.LinkTypeEthernet,
		HardwareLen:  6,
		HardwareOpts: 0,
		Xid:          uint32(xid),
		ClientHWAddr: mac,
	}
}

func createDefaultOpts(intfId uint32, onuId uint32) []layers.DHCPOption {
	hostname := []byte(fmt.Sprintf("%d.%d.bbsim.onf.org", intfId, onuId))
	opts := []layers.DHCPOption{}
	opts = append(opts, layers.DHCPOption{
		Type:   layers.DHCPOptHostname,
		Data:   hostname,
		Length: uint8(len(hostname)),
	})

	bytes := []byte{}
	for _, option := range defaultParamsRequestList {
		bytes = append(bytes, byte(option))
	}

	opts = append(opts, layers.DHCPOption{
		Type:   layers.DHCPOptParamsRequest,
		Data:   bytes,
		Length: uint8(len(bytes)),
	})
	return opts
}

func createDHCPDisc(oltId int, intfId uint32, onuId uint32, gemPort uint32, macAddress net.HardwareAddr) *layers.DHCPv4 {
	dhcpLayer := createDefaultDHCPReq(oltId, intfId, onuId, macAddress)
	defaultOpts := createDefaultOpts(intfId, onuId)
	dhcpLayer.Options = append([]layers.DHCPOption{{
		Type:   layers.DHCPOptMessageType,
		Data:   []byte{byte(layers.DHCPMsgTypeDiscover)},
		Length: 1,
	}}, defaultOpts...)

	data := []byte{0xcd, 0x28, 0xcb, 0xcc, 0x00, 0x01, 0x00, 0x01,
		0x23, 0xed, 0x11, 0xec, 0x4e, 0xfc, 0xcd, byte(intfId), byte(onuId), byte(gemPort)} //FIXME use the OLT-ID in here
	dhcpLayer.Options = append(dhcpLayer.Options, layers.DHCPOption{
		Type:   layers.DHCPOptClientID,
		Data:   data,
		Length: uint8(len(data)),
	})

	return &dhcpLayer
}

func createDHCPReq(oltId int, intfId uint32, onuId uint32, macAddress net.HardwareAddr, offeredIp net.IP) *layers.DHCPv4 {
	dhcpLayer := createDefaultDHCPReq(oltId, intfId, onuId, macAddress)
	defaultOpts := createDefaultOpts(intfId, onuId)

	dhcpLayer.Options = append(defaultOpts, layers.DHCPOption{
		Type:   layers.DHCPOptMessageType,
		Data:   []byte{byte(layers.DHCPMsgTypeRequest)},
		Length: 1,
	})

	data := []byte{182, 21, 0, 128}
	dhcpLayer.Options = append(dhcpLayer.Options, layers.DHCPOption{
		Type:   layers.DHCPOptServerID,
		Data:   data,
		Length: uint8(len(data)),
	})

	data = []byte{0xcd, 0x28, 0xcb, 0xcc, 0x00, 0x01, 0x00, 0x01,
		0x23, 0xed, 0x11, 0xec, 0x4e, 0xfc, 0xcd, 0x28, byte(intfId), byte(onuId)}
	dhcpLayer.Options = append(dhcpLayer.Options, layers.DHCPOption{
		Type:   layers.DHCPOptClientID,
		Data:   data,
		Length: uint8(len(data)),
	})

	// NOTE we should not request a specific IP, or we should request the one that has been offered
	dhcpLayer.Options = append(dhcpLayer.Options, layers.DHCPOption{
		Type:   layers.DHCPOptRequestIP,
		Data:   offeredIp,
		Length: uint8(len(offeredIp)),
	})
	return &dhcpLayer
}

func serializeDHCPPacket(intfId uint32, onuId uint32, cTag int, srcMac net.HardwareAddr, dhcp *layers.DHCPv4, pbit uint8) ([]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,
		TTL:      128,
		SrcIP:    []byte{0, 0, 0, 0},
		DstIP:    []byte{255, 255, 255, 255},
		Protocol: layers.IPProtocolUDP,
	}

	udpLayer := &layers.UDP{
		SrcPort: 68,
		DstPort: 67,
	}

	_ = udpLayer.SetNetworkLayerForChecksum(ipLayer)
	if err := gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, udpLayer, dhcp); err != nil {
		dhcpLogger.Error("SerializeLayers")
		return nil, err
	}

	untaggedPkt := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default)

	taggedPkt, err := packetHandlers.PushSingleTag(cTag, untaggedPkt, pbit)
	if err != nil {
		dhcpLogger.Error("TagPacket")
		return nil, err
	}

	return gopacket.Payload(taggedPkt.Data()), nil
}

func GetDhcpLayer(pkt gopacket.Packet) (*layers.DHCPv4, error) {
	layerDHCP := pkt.Layer(layers.LayerTypeDHCPv4)
	dhcp, _ := layerDHCP.(*layers.DHCPv4)
	if dhcp == nil {
		return nil, errors.New("Failed-to-extract-DHCP-layer")
	}
	return dhcp, nil
}

func GetDhcpMessageType(dhcp *layers.DHCPv4) (layers.DHCPMsgType, error) {
	for _, option := range dhcp.Options {
		if option.Type == layers.DHCPOptMessageType {
			if reflect.DeepEqual(option.Data, []byte{byte(layers.DHCPMsgTypeDiscover)}) {
				return layers.DHCPMsgTypeDiscover, nil
			} else if reflect.DeepEqual(option.Data, []byte{byte(layers.DHCPMsgTypeOffer)}) {
				return layers.DHCPMsgTypeOffer, nil
			} else if reflect.DeepEqual(option.Data, []byte{byte(layers.DHCPMsgTypeRequest)}) {
				return layers.DHCPMsgTypeRequest, nil
			} else if reflect.DeepEqual(option.Data, []byte{byte(layers.DHCPMsgTypeAck)}) {
				return layers.DHCPMsgTypeAck, nil
			} else if reflect.DeepEqual(option.Data, []byte{byte(layers.DHCPMsgTypeRelease)}) {
				return layers.DHCPMsgTypeRelease, nil
			} else {
				msg := fmt.Sprintf("This type %x is not supported", option.Data)
				return 0, errors.New(msg)
			}
		}
	}
	return 0, errors.New("Failed to extract MsgType from dhcp")
}

// returns the DHCP Layer type or error if it's not a DHCP Packet
func GetDhcpPacketType(pkt gopacket.Packet) (string, error) {
	dhcpLayer, err := GetDhcpLayer(pkt)
	if err != nil {
		return "", err
	}
	dhcpMessageType, err := GetDhcpMessageType(dhcpLayer)
	if err != nil {
		return "", err
	}

	return dhcpMessageType.String(), nil
}

func sendDHCPPktIn(msg bbsim.ByteMsg, portNo uint32, gemPortId uint32, stream bbsim.Stream) error {

	dhcpLogger.WithFields(log.Fields{
		"OnuId":   msg.OnuId,
		"IntfId":  msg.IntfId,
		"GemPort": gemPortId,
		"Type":    "DHCP",
		"Pkt":     hex.EncodeToString(msg.Bytes),
	}).Trace("Sending DHCP packet in")

	data := &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{
		IntfType:  "pon",
		IntfId:    msg.IntfId,
		GemportId: gemPortId,
		Pkt:       msg.Bytes,
		PortNo:    portNo,
	}}

	if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
		dhcpLogger.Errorf("Fail to send DHCP PktInd indication. %v", err)
		return err
	}
	return nil
}

func sendDHCPRequest(oltId int, ponPortId uint32, onuId uint32, serviceName string, serialNumber string, portNo uint32,
	cTag int, gemPortId uint32, onuStateMachine *fsm.FSM, onuHwAddress net.HardwareAddr,
	offeredIp net.IP, pbit uint8, stream bbsim.Stream) error {
	dhcp := createDHCPReq(oltId, ponPortId, onuId, onuHwAddress, offeredIp)
	pkt, err := serializeDHCPPacket(ponPortId, onuId, cTag, onuHwAddress, dhcp, pbit)

	if err != nil {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":     onuId,
			"IntfId":    ponPortId,
			"OnuSn":     serialNumber,
			"OfferedIp": offeredIp.String(),
		}).Errorf("Cannot serializeDHCPPacket: %s", err)
		if err := updateDhcpFailed(onuId, ponPortId, serialNumber, onuStateMachine); err != nil {
			return err
		}
		return err
	}
	// NOTE I don't think we need to tag the packet
	//taggedPkt, err := packetHandlers.PushSingleTag(cTag, pkt)

	msg := bbsim.ByteMsg{
		IntfId: ponPortId,
		OnuId:  onuId,
		Bytes:  pkt,
	}

	if err := sendDHCPPktIn(msg, portNo, gemPortId, stream); err != nil {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
		}).Errorf("Cannot sendDHCPPktIn: %s", err)
		if err := updateDhcpFailed(onuId, ponPortId, serialNumber, onuStateMachine); err != nil {
			return err
		}
		return err
	}

	dhcpLogger.WithFields(log.Fields{
		"OnuId":       onuId,
		"IntfId":      ponPortId,
		"OnuSn":       serialNumber,
		"OfferedIp":   offeredIp.String(),
		"ServiceName": serviceName,
	}).Infof("DHCPRequest Sent")
	return nil
}

func updateDhcpFailed(onuId uint32, ponPortId uint32, serialNumber string, onuStateMachine *fsm.FSM) error {
	if err := onuStateMachine.Event("dhcp_failed"); err != nil {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
		}).Errorf("Error while transitioning ONU State %v", err)
		return err
	}
	return nil
}

func SendDHCPDiscovery(oltId int, ponPortId uint32, onuId uint32, serviceName string, cTag int, gemPortId uint32,
	serialNumber string, portNo uint32, stateMachine *fsm.FSM, onuHwAddress net.HardwareAddr,
	pbit uint8, stream bbsim.Stream) error {

	dhcp := createDHCPDisc(oltId, ponPortId, onuId, gemPortId, onuHwAddress)
	pkt, err := serializeDHCPPacket(ponPortId, onuId, cTag, onuHwAddress, dhcp, pbit)

	if err != nil {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":       onuId,
			"IntfId":      ponPortId,
			"OnuSn":       serialNumber,
			"ServiceName": serviceName,
		}).Errorf("Cannot serializeDHCPPacket: %s", err)
		if err := updateDhcpFailed(onuId, ponPortId, serialNumber, stateMachine); err != nil {
			return err
		}
		return err
	}
	// NOTE I don't think we need to tag the packet
	//taggedPkt, err := packetHandlers.PushSingleTag(cTag, pkt)

	msg := bbsim.ByteMsg{
		IntfId: ponPortId,
		OnuId:  onuId,
		Bytes:  pkt,
	}

	if err := sendDHCPPktIn(msg, portNo, gemPortId, stream); err != nil {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":       onuId,
			"IntfId":      ponPortId,
			"OnuSn":       serialNumber,
			"ServiceName": serviceName,
		}).Errorf("Cannot sendDHCPPktIn: %s", err)
		if err := updateDhcpFailed(onuId, ponPortId, serialNumber, stateMachine); err != nil {
			return err
		}
		return err
	}
	dhcpLogger.WithFields(log.Fields{
		"OnuId":       onuId,
		"IntfId":      ponPortId,
		"OnuSn":       serialNumber,
		"ServiceName": serviceName,
	}).Info("DHCPDiscovery Sent")

	if err := stateMachine.Event("dhcp_discovery_sent"); err != nil {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":       onuId,
			"IntfId":      ponPortId,
			"OnuSn":       serialNumber,
			"ServiceName": serviceName,
		}).Errorf("Error while transitioning ONU State %v", err)
	}
	return nil
}

func HandleNextPacket(oltId int, onuId uint32, ponPortId uint32, serviceName string, serialNumber string, portNo uint32,
	cTag int, gemPortId uint32, onuHwAddress net.HardwareAddr, onuStateMachine *fsm.FSM,
	pkt gopacket.Packet, pbit uint8, stream bbsim.Stream) error {

	dhcpLayer, err := GetDhcpLayer(pkt)
	if err != nil {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":       onuId,
			"IntfId":      ponPortId,
			"OnuSn":       serialNumber,
			"ServiceName": serviceName,
		}).Errorf("Can't get DHCP Layer from Packet: %v", err)
		if err := updateDhcpFailed(onuId, ponPortId, serialNumber, onuStateMachine); err != nil {
			return err
		}
		return err
	}
	dhcpMessageType, err := GetDhcpMessageType(dhcpLayer)
	if err != nil {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":       onuId,
			"IntfId":      ponPortId,
			"OnuSn":       serialNumber,
			"ServiceName": serviceName,
		}).Errorf("Can't get DHCP Message Type from DHCP Layer: %v", err)
		if err := updateDhcpFailed(onuId, ponPortId, serialNumber, onuStateMachine); err != nil {
			return err
		}
		return err
	}

	if dhcpLayer.Operation == layers.DHCPOpReply {
		if dhcpMessageType == layers.DHCPMsgTypeOffer {
			offeredIp := dhcpLayer.YourClientIP
			if err := sendDHCPRequest(oltId, ponPortId, onuId, serviceName, serialNumber, portNo, cTag, gemPortId, onuStateMachine, onuHwAddress, offeredIp, pbit, stream); err != nil {
				dhcpLogger.WithFields(log.Fields{
					"OnuId":       onuId,
					"IntfId":      ponPortId,
					"OnuSn":       serialNumber,
					"ServiceName": serviceName,
				}).Errorf("Can't send DHCP Request: %s", err)
				if err := updateDhcpFailed(onuId, ponPortId, serialNumber, onuStateMachine); err != nil {
					return err
				}
				return err
			}
			if err := onuStateMachine.Event("dhcp_request_sent"); err != nil {
				dhcpLogger.WithFields(log.Fields{
					"OnuId":       onuId,
					"IntfId":      ponPortId,
					"OnuSn":       serialNumber,
					"ServiceName": serviceName,
				}).Errorf("Error while transitioning State %v", err)
			}

		} else if dhcpMessageType == layers.DHCPMsgTypeAck {
			// NOTE once the ack is received we don't need to do anything but change the state
			if err := onuStateMachine.Event("dhcp_ack_received"); err != nil {
				dhcpLogger.WithFields(log.Fields{
					"OnuId":       onuId,
					"IntfId":      ponPortId,
					"OnuSn":       serialNumber,
					"ServiceName": serviceName,
				}).Errorf("Error while transitioning State %v", err)
			}
			dhcpLogger.WithFields(log.Fields{
				"OnuId":       onuId,
				"IntfId":      ponPortId,
				"OnuSn":       serialNumber,
				"ServiceName": serviceName,
			}).Infof("DHCP State machine completed")
		}
		// NOTE do we need to care about DHCPMsgTypeRelease??
	} else {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":       onuId,
			"IntfId":      ponPortId,
			"OnuSn":       serialNumber,
			"ServiceName": serviceName,
		}).Warnf("Unsupported DHCP Operation: %s", dhcpLayer.Operation.String())
	}

	return nil
}

// This method handle the BBR DHCP Packets
// BBR does not need to do anything but forward the packets in the correct direction
func HandleNextBbrPacket(onuId uint32, ponPortId uint32, serialNumber string, doneChannel chan bool, pkt gopacket.Packet, client openolt.OpenoltClient) error {

	// check if the packet is going:
	// - outgouing: toward the DHCP
	// - incoming: toward the ONU
	isIncoming := packetHandlers.IsIncomingPacket(pkt)
	dhcpLogger.Tracef("Is Incoming: %t", isIncoming)

	pkt, err := packetHandlers.PopSingleTag(pkt)
	if err != nil {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
			"error":  err,
		}).Fatalf("Can't untag packet")
	}

	dhcpType, err := GetDhcpPacketType(pkt)
	if err != nil {
		dhcpLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
			"error":  err,
		}).Fatalf("Can't find DHCP type for packet")
	}

	srcMac, _ := packetHandlers.GetSrcMacAddressFromPacket(pkt)
	dstMac, _ := packetHandlers.GetDstMacAddressFromPacket(pkt)

	if isIncoming {

		onuPacket := openolt.OnuPacket{
			IntfId:    ponPortId,
			OnuId:     onuId,
			PortNo:    onuId,
			GemportId: 1,
			Pkt:       pkt.Data(),
		}

		if _, err := client.OnuPacketOut(context.Background(), &onuPacket); err != nil {
			dhcpLogger.WithFields(log.Fields{
				"OnuId":  onuId,
				"IntfId": ponPortId,
				"OnuSn":  serialNumber,
				"Type":   dhcpType,
				"error":  err,
			}).Error("Failed to send DHCP packet to the ONU")
		}

		dhcpLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
			"Type":   dhcpType,
			"DstMac": dstMac,
			"SrcMac": srcMac,
		}).Infof("Sent DHCP packet to the ONU")

		dhcpLayer, _ := GetDhcpLayer(pkt)
		dhcpMessageType, _ := GetDhcpMessageType(dhcpLayer)
		if dhcpMessageType == layers.DHCPMsgTypeAck {
			doneChannel <- true
		}

	} else {
		// double tag the packet and send it to the NNI
		// we don't really care about the tags as they are stripped before
		// the packet is sent to the DHCP server
		// in BBR we don't care about the pBit
		doubleTaggedPkt, err := packetHandlers.PushDoubleTag(900, 900, pkt, 0)
		if err != nil {
			dhcpLogger.WithFields(log.Fields{
				"OnuId":  onuId,
				"IntfId": ponPortId,
				"OnuSn":  serialNumber,
				"Type":   dhcpType,
				"error":  err,
			}).Error("Failed to add double tag to packet")
		}

		pkt := openolt.UplinkPacket{
			IntfId: 0, // BBSim does not care about which NNI, it has only one
			Pkt:    doubleTaggedPkt.Data(),
		}
		if _, err := client.UplinkPacketOut(context.Background(), &pkt); err != nil {
			dhcpLogger.WithFields(log.Fields{
				"OnuId":  onuId,
				"IntfId": ponPortId,
				"OnuSn":  serialNumber,
				"Type":   dhcpType,
				"error":  err,
			}).Error("Failed to send DHCP packet out of the NNI Port")
		}
		dhcpLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
			"Type":   dhcpType,
			"DstMac": dstMac,
			"SrcMac": srcMac,
		}).Infof("Sent DHCP packet out of the NNI Port")
	}
	return nil
}
