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

import (
	"context"
	"encoding/hex"
	"errors"
	"fmt"
	"math/rand"
	"net"
	"reflect"
	"sync"

	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/opencord/voltha-bbsim/common/logger"
)

// Constants for DHCP states
const (
	DhcpInit clientState = iota + 1
	DhcpSelecting
	DhcpRequesting
	DhcpBound
)

type dhcpResponder struct {
	clients map[clientKey]*dhcpClientInstance
	dhcpIn  chan *byteMsg
}

type dhcpClientInstance struct {
	key      clientKey
	srcaddr  *net.HardwareAddr
	srcIP    *net.IPAddr
	serverIP *net.IPAddr
	hostname string
	curID    uint32
	curState clientState
}

var dhcpresp *dhcpResponder
var dhcponce sync.Once

func getDHCPResponder() *dhcpResponder {
	dhcponce.Do(func() {
		dhcpresp = &dhcpResponder{clients: make(map[clientKey]*dhcpClientInstance), dhcpIn: nil}
	})
	return dhcpresp
}

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

// RunDhcpResponder responds to the DHCP client messages
func RunDhcpResponder(ctx context.Context, dhcpOut chan *byteMsg, dhcpIn chan *byteMsg, errch chan error) {
	responder := getDHCPResponder()
	responder.dhcpIn = dhcpIn
	clients := responder.clients

	go func() {
		logger.Debug("DHCP response process starts")
		defer logger.Debug("DHCP response process was done")
		for {
			select {
			case msg := <-dhcpOut:
				logger.Debug("Received dhcp message from dhcpOut")

				if c, ok := clients[clientKey{intfid: msg.IntfID, onuid: msg.OnuID}]; ok {
					nextstate := respondMessage("DHCP", *c, msg, dhcpIn)
					c.updateState(nextstate)
				} else {
					logger.Error("Failed to find dhcp client instance intfid:%d onuid:%d", msg.IntfID, msg.OnuID)
				}
			case <-ctx.Done():
				return
			}
		}
	}()
}

func startDHCPClient(intfid uint32, onuid uint32) error {
	logger.Debug("startDHCPClient intfid:%d onuid:%d", intfid, onuid)
	client := dhcpClientInstance{key: clientKey{intfid: intfid, onuid: onuid},
		srcaddr:  &net.HardwareAddr{0x2e, 0x60, 0x70, 0x13, 0x07, byte(onuid)},
		hostname: "voltha",
		curID:    rand.Uint32(),
		curState: DhcpInit}

	dhcp := client.createDHCPDisc()
	bytes, err := client.createDHCP(dhcp)
	if err != nil {
		logger.Error("%s", err)
		return err
	}
	resp := getDHCPResponder()
	dhcpIn := resp.dhcpIn
	if err := client.sendBytes(bytes, dhcpIn); err != nil {
		logger.Error("Failed to send DHCP Discovery")
		return errors.New("failed to send DHCP Discovery")
	}
	client.curState = DhcpSelecting
	logger.Debug("Sending DHCP Discovery intfid:%d onuid:%d", intfid, onuid)
	resp.clients[clientKey{intfid: intfid, onuid: onuid}] = &client
	return nil
}

func (c dhcpClientInstance) transitState(cur clientState, recvbytes []byte) (next clientState, sendbytes []byte, err error) {
	recvpkt := gopacket.NewPacket(recvbytes, layers.LayerTypeEthernet, gopacket.Default)
	dhcp, err := extractDHCP(recvpkt)
	if err != nil {
		return cur, nil, nil
	}
	msgType, err := getMsgType(dhcp)
	if err != nil {
		logger.Error("%s", err)
		return cur, nil, nil
	}
	if dhcp.Operation == layers.DHCPOpReply && msgType == layers.DHCPMsgTypeOffer {
		logger.Debug("Received DHCP Offer")
		logger.Debug(recvpkt.Dump())
		if cur == DhcpSelecting {
			senddhcp := c.createDHCPReq()
			sendbytes, err := c.createDHCP(senddhcp)
			if err != nil {
				logger.Debug("Failed to createDHCP")
				return cur, nil, err
			}
			return DhcpRequesting, sendbytes, nil
		}
	} else if dhcp.Operation == layers.DHCPOpReply && msgType == layers.DHCPMsgTypeAck {
		logger.Debug("Received DHCP Ack")
		logger.Debug(recvpkt.Dump())
		if cur == DhcpRequesting {
			return DhcpBound, nil, nil
		}
	} else if dhcp.Operation == layers.DHCPOpReply && msgType == layers.DHCPMsgTypeRelease {
		if cur == DhcpBound {
			senddhcp := c.createDHCPDisc()
			sendbytes, err := c.createDHCP(senddhcp)
			if err != nil {
				fmt.Println("Failed to createDHCP")
				return DhcpInit, nil, err
			}
			return DhcpSelecting, sendbytes, nil
		}
	} else {
		logger.Debug("Received unsupported DHCP message Operation:%d MsgType:%d", dhcp.Operation, msgType)
		return cur, nil, nil
	}
	logger.Error("State transition does not support..current state:%d", cur)
	logger.Debug(recvpkt.Dump())

	return cur, nil, nil
}

func (c dhcpClientInstance) getState() clientState {
	return c.curState
}

func (c *dhcpClientInstance) updateState(state clientState) {
	msg := fmt.Sprintf("DHCP update state intfid:%d onuid:%d state:%d", c.key.intfid, c.key.onuid, state)
	logger.Debug(msg)
	c.curState = state
}

func (c dhcpClientInstance) getKey() clientKey {
	return c.key
}

func (c *dhcpClientInstance) createDHCP(dhcp *layers.DHCPv4) ([]byte, error) {
	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{
		ComputeChecksums: true,
		FixLengths:       true,
	}
	ethernetLayer := &layers.Ethernet{
		SrcMAC:       *c.srcaddr,
		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,
	}

	err := udpLayer.SetNetworkLayerForChecksum(ipLayer)
	if err != nil {
		return nil, err
	}

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

	bytes := buffer.Bytes()
	return bytes, nil
}

func (c *dhcpClientInstance) createDefaultDHCPReq() layers.DHCPv4 {
	return layers.DHCPv4{
		Operation:    layers.DHCPOpRequest,
		HardwareType: layers.LinkTypeEthernet,
		HardwareLen:  6,
		HardwareOpts: 0,
		Xid:          c.curID,
		ClientHWAddr: *c.srcaddr,
	}
}

func (c *dhcpClientInstance) createDefaultOpts() []layers.DHCPOption {
	hostname := []byte(c.hostname)
	var opts []layers.DHCPOption
	opts = append(opts, layers.DHCPOption{
		Type:   layers.DHCPOptHostname,
		Data:   hostname,
		Length: uint8(len(hostname)),
	})

	var 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 (c *dhcpClientInstance) createDHCPDisc() *layers.DHCPv4 {
	dhcpLayer := c.createDefaultDHCPReq()
	defaultOpts := c.createDefaultOpts()
	dhcpLayer.Options = append([]layers.DHCPOption{{
		Type:   layers.DHCPOptMessageType,
		Data:   []byte{byte(layers.DHCPMsgTypeDiscover)},
		Length: 1,
	}}, defaultOpts...)

	return &dhcpLayer
}

func (c *dhcpClientInstance) createDHCPReq() *layers.DHCPv4 {
	dhcpLayer := c.createDefaultDHCPReq()
	defaultOpts := c.createDefaultOpts()
	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, 0xcb, 0xcc}
	dhcpLayer.Options = append(dhcpLayer.Options, layers.DHCPOption{
		Type:   layers.DHCPOptClientID,
		Data:   data,
		Length: uint8(len(data)),
	})

	data = []byte{182, 21, 0, byte(c.key.onuid)}
	dhcpLayer.Options = append(dhcpLayer.Options, layers.DHCPOption{
		Type:   layers.DHCPOptRequestIP,
		Data:   data,
		Length: uint8(len(data)),
	})
	return &dhcpLayer
}

func (c *dhcpClientInstance) sendBytes(bytes []byte, dhcpIn chan *byteMsg) error {
	// Send our packet
	msg := byteMsg{IntfID: c.key.intfid,
		OnuID: c.key.onuid,
		Byte:  bytes}
	dhcpIn <- &msg
	logger.Debug("sendBytes intfid:%d onuid:%d", c.key.intfid, c.key.onuid)
	logger.Debug(hex.Dump(msg.Byte))
	return nil
}

func extractDHCP(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")
	}
	return dhcp, nil
}

func getMsgType(dhcp *layers.DHCPv4) (layers.DHCPMsgType, error) {
	for _, option := range dhcp.Options {
		if option.Type == layers.DHCPOptMessageType {
			if reflect.DeepEqual(option.Data, []byte{byte(layers.DHCPMsgTypeOffer)}) {
				return layers.DHCPMsgTypeOffer, 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")
}
