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

import (
	"context"
	"crypto/md5"
	"errors"
	"net"

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

var eapolLogger = log.WithFields(log.Fields{
	"module": "EAPOL",
})

var eapolVersion uint8 = 1
var GetGemPortId = omci.GetGemPortId

func sendEapolPktIn(msg bbsim.ByteMsg, portNo uint32, gemid uint32, stream bbsim.Stream) error {
	// FIXME unify sendDHCPPktIn and sendEapolPktIn methods

	log.WithFields(log.Fields{
		"OnuId":   msg.OnuId,
		"IntfId":  msg.IntfId,
		"GemPort": gemid,
		"Type":    "EAPOL",
	}).Trace("sending-pkt")

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

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

func getMD5Data(eap *layers.EAP) []byte {
	i := byte(eap.Id)
	C := []byte(eap.BaseLayer.Contents)[6:]
	P := []byte{i, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64} // "password"
	data := md5.Sum(append(P, C...))
	ret := make([]byte, 16)
	for j := 0; j < 16; j++ {
		ret[j] = data[j]
	}
	return ret
}

func createEAPChallengeRequest(eapId uint8, payload []byte) *layers.EAP {
	eap := layers.EAP{
		Code:     layers.EAPCodeRequest,
		Id:       eapId,
		Length:   22,
		Type:     layers.EAPTypeOTP,
		TypeData: payload,
	}
	return &eap
}

func createEAPChallengeResponse(eapId uint8, payload []byte) *layers.EAP {
	eap := layers.EAP{
		Code:     layers.EAPCodeResponse,
		Id:       eapId,
		Length:   22,
		Type:     layers.EAPTypeOTP,
		TypeData: payload,
	}
	return &eap
}

func createEAPIdentityRequest(eapId uint8) *layers.EAP {
	eap := layers.EAP{Code: layers.EAPCodeRequest,
		Id:       eapId,
		Length:   9,
		Type:     layers.EAPTypeIdentity,
		TypeData: []byte{0x75, 0x73, 0x65, 0x72}}
	return &eap
}

func createEAPIdentityResponse(eapId uint8) *layers.EAP {
	eap := layers.EAP{Code: layers.EAPCodeResponse,
		Id:       eapId,
		Length:   9,
		Type:     layers.EAPTypeIdentity,
		TypeData: []byte{0x75, 0x73, 0x65, 0x72}}
	return &eap
}

func createEAPSuccess(eapId uint8) *layers.EAP {
	eap := layers.EAP{
		Code:     layers.EAPCodeSuccess,
		Id:       eapId,
		Length:   9,
		Type:     layers.EAPTypeNone,
		TypeData: []byte{0x75, 0x73, 0x65, 0x72}}
	return &eap
}

func createEAPOLPkt(eap *layers.EAP, onuId uint32, intfId uint32) []byte {
	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{}

	ethernetLayer := &layers.Ethernet{
		SrcMAC:       net.HardwareAddr{0x2e, 0x60, byte(0), byte(intfId), byte(onuId), byte(0)},
		DstMAC:       net.HardwareAddr{0x2e, 0x60, byte(0), byte(intfId), byte(onuId), byte(0)},
		EthernetType: layers.EthernetTypeEAPOL,
	}

	_ = gopacket.SerializeLayers(buffer, options,
		ethernetLayer,
		&layers.EAPOL{Version: eapolVersion, Type: 0, Length: eap.Length},
		eap,
	)

	bytes := buffer.Bytes()
	return bytes
}

func extractEAP(pkt gopacket.Packet) (*layers.EAP, error) {
	layerEAP := pkt.Layer(layers.LayerTypeEAP)
	eap, _ := layerEAP.(*layers.EAP)
	if eap == nil {
		return nil, errors.New("Cannot extract EAP")
	}
	return eap, nil
}

func extractEAPOL(pkt gopacket.Packet) (*layers.EAPOL, error) {
	layerEAPOL := pkt.Layer(layers.LayerTypeEAPOL)
	eap, _ := layerEAPOL.(*layers.EAPOL)
	if eap == nil {
		return nil, errors.New("Cannot extract EAPOL")
	}
	return eap, nil
}

func sendEapolPktOut(client openolt.OpenoltClient, intfId uint32, onuId uint32, pkt []byte) error {
	onuPacket := openolt.OnuPacket{
		IntfId:    intfId,
		OnuId:     onuId,
		PortNo:    onuId,
		GemportId: 1,
		Pkt:       pkt,
	}

	if _, err := client.OnuPacketOut(context.Background(), &onuPacket); err != nil {
		return err
	}
	return nil
}

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

func SendEapStart(onuId uint32, ponPortId uint32, serialNumber string, portNo uint32, macAddress net.HardwareAddr, gemPort uint32, stateMachine *fsm.FSM, stream bbsim.Stream) error {

	// TODO use createEAPOLPkt
	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{}

	ethernetLayer := &layers.Ethernet{
		SrcMAC:       macAddress,
		DstMAC:       net.HardwareAddr{0x01, 0x80, 0xC2, 0x00, 0x00, 0x03},
		EthernetType: layers.EthernetTypeEAPOL,
	}

	_ = gopacket.SerializeLayers(buffer, options,
		ethernetLayer,
		&layers.EAPOL{Version: eapolVersion, Type: 1, Length: 0},
	)

	msg := buffer.Bytes()
	// TODO end createEAPOLPkt

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

	err := stream.Send(&openolt.Indication{Data: data})
	if err != nil {
		eapolLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
		}).Errorf("Can't send EapStart Message: %s", err)

		if err := updateAuthFailed(onuId, ponPortId, serialNumber, stateMachine); err != nil {
			return err
		}
		return err
	}

	eapolLogger.WithFields(log.Fields{
		"OnuId":  onuId,
		"IntfId": ponPortId,
		"OnuSn":  serialNumber,
		"PortNo": portNo,
	}).Debugf("Sent EapStart packet")

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

func HandleNextPacket(onuId uint32, ponPortId uint32, gemPortId uint32, serialNumber string, portNo uint32, stateMachine *fsm.FSM, pkt gopacket.Packet, stream bbsim.Stream, client openolt.OpenoltClient) {

	eap, eapErr := extractEAP(pkt)

	eapol, eapolErr := extractEAPOL(pkt)

	if eapErr != nil && eapolErr != nil {
		log.Fatalf("Failed to Extract EAP: %v - %v", eapErr, eapolErr)
		return
	}

	fields := log.Fields{}
	if eap != nil {
		fields = log.Fields{
			"Code":   eap.Code,
			"Type":   eap.Type,
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
		}
	} else if eapol != nil {
		fields = log.Fields{
			"Type":   eapol.Type,
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
		}
	}

	log.WithFields(fields).Tracef("Handle Next EAPOL Packet")

	if eapol != nil && eapol.Type == layers.EAPOLTypeStart {
		identityRequest := createEAPIdentityRequest(1)
		pkt := createEAPOLPkt(identityRequest, onuId, ponPortId)

		if err := sendEapolPktOut(client, ponPortId, onuId, pkt); err != nil {
			log.WithFields(log.Fields{
				"OnuId":  onuId,
				"IntfId": ponPortId,
				"OnuSn":  serialNumber,
				"error":  err,
			}).Errorf("Error while sending EAPIdentityRequest packet")
			return
		}

		log.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
		}).Infof("Sent EAPIdentityRequest packet")
		return
	} else if eap.Code == layers.EAPCodeRequest && eap.Type == layers.EAPTypeIdentity {
		reseap := createEAPIdentityResponse(eap.Id)
		pkt := createEAPOLPkt(reseap, onuId, ponPortId)

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

		if err := sendEapolPktIn(msg, portNo, gemPortId, stream); err != nil {
			_ = stateMachine.Event("auth_failed")
			return
		}
		eapolLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
			"PortNo": portNo,
		}).Debugf("Sent EAPIdentityResponse packet")
		if err := stateMachine.Event("eap_response_identity_sent"); err != nil {
			eapolLogger.WithFields(log.Fields{
				"OnuId":  onuId,
				"IntfId": ponPortId,
				"OnuSn":  serialNumber,
			}).Errorf("Error while transitioning ONU State %v", err)
		}

	} else if eap.Code == layers.EAPCodeResponse && eap.Type == layers.EAPTypeIdentity {
		senddata := getMD5Data(eap)
		senddata = append([]byte{0x10}, senddata...)
		challengeRequest := createEAPChallengeRequest(eap.Id, senddata)
		pkt := createEAPOLPkt(challengeRequest, onuId, ponPortId)

		if err := sendEapolPktOut(client, ponPortId, onuId, pkt); err != nil {
			log.WithFields(log.Fields{
				"OnuId":  onuId,
				"IntfId": ponPortId,
				"OnuSn":  serialNumber,
				"error":  err,
			}).Errorf("Error while sending EAPChallengeRequest packet")
			return
		}
		log.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
		}).Infof("Sent EAPChallengeRequest packet")
		return
	} else if eap.Code == layers.EAPCodeRequest && eap.Type == layers.EAPTypeOTP {
		senddata := getMD5Data(eap)
		senddata = append([]byte{0x10}, senddata...)
		sendeap := createEAPChallengeResponse(eap.Id, senddata)
		pkt := createEAPOLPkt(sendeap, onuId, ponPortId)

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

		if err := sendEapolPktIn(msg, portNo, gemPortId, stream); err != nil {
			_ = stateMachine.Event("auth_failed")
			return
		}
		eapolLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
			"PortNo": portNo,
		}).Debugf("Sent EAPChallengeResponse packet")
		if err := stateMachine.Event("eap_response_challenge_sent"); err != nil {
			eapolLogger.WithFields(log.Fields{
				"OnuId":  onuId,
				"IntfId": ponPortId,
				"OnuSn":  serialNumber,
			}).Errorf("Error while transitioning ONU State %v", err)
		}
	} else if eap.Code == layers.EAPCodeResponse && eap.Type == layers.EAPTypeOTP {
		eapSuccess := createEAPSuccess(eap.Id)
		pkt := createEAPOLPkt(eapSuccess, onuId, ponPortId)

		if err := sendEapolPktOut(client, ponPortId, onuId, pkt); err != nil {
			log.WithFields(log.Fields{
				"OnuId":  onuId,
				"IntfId": ponPortId,
				"OnuSn":  serialNumber,
				"error":  err,
			}).Errorf("Error while sending EAPSuccess packet")
			return
		}

		log.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
		}).Infof("Sent EAP Success packet")

		if err := stateMachine.Event("send_dhcp_flow"); err != nil {
			eapolLogger.WithFields(log.Fields{
				"OnuId":  onuId,
				"IntfId": ponPortId,
				"OnuSn":  serialNumber,
			}).Errorf("Error while transitioning ONU State %v", err)
		}
	} else if eap.Code == layers.EAPCodeSuccess && eap.Type == layers.EAPTypeNone {
		eapolLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
			"PortNo": portNo,
		}).Debugf("Received EAPSuccess packet")
		if err := stateMachine.Event("eap_response_success_received"); err != nil {
			eapolLogger.WithFields(log.Fields{
				"OnuId":  onuId,
				"IntfId": ponPortId,
				"OnuSn":  serialNumber,
			}).Errorf("Error while transitioning ONU State %v", err)
		}
		eapolLogger.WithFields(log.Fields{
			"OnuId":  onuId,
			"IntfId": ponPortId,
			"OnuSn":  serialNumber,
		}).Infof("EAPOL State machine completed")
		return
	}
}
