/*
* Copyright 2022-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 application

import (
	"sync"
	"time"

	"voltha-go-controller/log"
)

const (
	dhcpTimeout uint8 = 60
)

// done channel required to gracefully stop dhcp server handler thread
var done = make(chan bool)

// dhcpServerInfo map having dhcp network as key and dhcp request response transaction as value
var dhcpServerInfo map[dhcpServerTag]dhcpTransactionInfo

// alarmsRaised is struct having array of dhcp network for which dhcp unreachable alarm raised
var alarmsRaised alarmsRaisedInfo

// mux is mutex variable used for lock unlock
var mux sync.Mutex

// StartDhcpServerHandler starts go routine periodically(every second) to verify DHCP server reachability.
func StartDhcpServerHandler() {
	// Initialize global dhcp map and ticker as one second
	dhcpServerInfo = make(map[dhcpServerTag]dhcpTransactionInfo)
	ticker := time.NewTicker(1 * time.Second)

	// go routine runs checkDhcpTimeout every second and exit if done value is set.
	go func() {
		for {
			select {
			case <-done:
				ticker.Stop()
				return
			case <-ticker.C:
				mux.Lock()
				checkDhcpTimeout()
				mux.Unlock()
			}
		}
	}()
}

// checkDhcpTimeout method called every second to verify dhcp timeout for each DHCP network
func checkDhcpTimeout() {
	// logger.Debugw(ctx, "[dhcptimeout] DHCP MAP Info", log.Fields{"Map": dhcpServerInfo})
	for dsTag, dtInfo := range dhcpServerInfo {
		dtInfo.decrementTimer()
		if dtInfo.getTimer() == 0 {
			logger.Debugw(ctx, "[dhcptimeout]Timer Expired", log.Fields{"ctag": dsTag.cTag, "stag": dsTag.sTag})
			if dtInfo.getReceivedResponseCount() == 0 && !alarmsRaised.isexist(dsTag) {
				alarmsRaised.add(dsTag)
				logger.Infow(ctx, "Alarms Raised", log.Fields{"ctag": dsTag.cTag, "stag": dsTag.sTag})
			}

			// Reset helps in
			// case 1: when 2 requests, 1 response received within timeout interval.
			// case 2: 1 request and no response even after timeout. (Unreachable alarm raised)
			// In both cases, reset method provides additional timeout to receive response before deleting
			dtInfo.resetRequestResponseCount(dhcpTimeout)

			// Delete dhcp entry in map and continue to process next entry if pending request set to 0
			if dtInfo.getPendingRequestCount() == 0 {
				delete(dhcpServerInfo, dsTag)
				logger.Debugw(ctx, "[dhcptimeout]DhcpServerTag info removed", log.Fields{"ctag": dsTag.cTag, "stag": dsTag.sTag})
				// logger.Debugw(ctx, "[dhcptimeout] DHCP MAP Info", log.Fields{"Map": dhcpServerInfo})
				continue
			}
		}
		// Update decremented timer value and continue loop
		dhcpServerInfo[dsTag] = dtInfo
	}
}

// dhcpRequestReceived called for every DHCP request received from client.
func dhcpRequestReceived(cTag, sTag uint16, smac string) {
	var dtInfo dhcpTransactionInfo
	var valueExist bool
	dsTag := newDhcpServerTag(cTag, sTag)

	mux.Lock()
	logger.Debugw(ctx, "dhcpRequestReceived", log.Fields{"ctag": cTag, "stag": sTag, "smac": smac})
	if dtInfo, valueExist = dhcpServerInfo[dsTag]; !valueExist {
		dtInfo = newDhcpTransactionInfo(dhcpTimeout, smac)
		dtInfo.incrementPendingRequestCount()
	}

	// Source mac received in dhcp request is not same as dtInfo mac then
	// Its new subscriber request, hence increment pending request count.
	// If multiple dhcp request received with same mac are ignored.
	if dtInfo.smac != smac {
		dtInfo.incrementPendingRequestCount()
	}

	dhcpServerInfo[dsTag] = dtInfo
	mux.Unlock()
}

// dhcpResponseReceived called for every DHCP response received from dhcp server.
func dhcpResponseReceived(cTag, sTag uint16) {
	var dtInfo dhcpTransactionInfo
	var valueExist bool
	dsTag := newDhcpServerTag(cTag, sTag)

	mux.Lock()
	logger.Debugw(ctx, "dhcpResponseReceived", log.Fields{"ctag": cTag, "stag": sTag})
	if dtInfo, valueExist = dhcpServerInfo[dsTag]; !valueExist {
		logger.Warnw(ctx, "Ignore unknown response", log.Fields{"DhcpResp": dsTag})
		mux.Unlock()
		return
	}

	// If already unreachable alarm raised, clear and remove from array
	if alarmsRaised.isexist(dsTag) {
		alarmsRaised.remove(dsTag)
		logger.Infow(ctx, "Alarm Cleared", log.Fields{"ctag": dsTag.cTag, "stag": dsTag.sTag})
	}

	// Increments received count and decrement pending count
	dtInfo.responseReceived()
	logger.Debugw(ctx, "Updated dtInfo", log.Fields{"pendingReq": dtInfo.pendingRequestCount, "receivedReq": dtInfo.receivedResponseCount})

	if dtInfo.getPendingRequestCount() == 0 {
		delete(dhcpServerInfo, dsTag)
	} else {
		dhcpServerInfo[dsTag] = dtInfo
	}
	mux.Unlock()
}

// StopDhcpServerHandler stops dhcp server handler go routine
func StopDhcpServerHandler() {
	done <- true
}

// dhcpServerTag contains unique dhcp network information
type dhcpServerTag struct {
	sTag uint16
	cTag uint16
}

func newDhcpServerTag(cTag, sTag uint16) dhcpServerTag {
	var d dhcpServerTag
	d.sTag = sTag
	d.cTag = cTag
	return d
}

// dhcpTransactionInfo contains DHCP request response transaction information.
type dhcpTransactionInfo struct {
	smac                  string
	pendingRequestCount   uint32
	receivedResponseCount uint32
	previousRequestCount  uint32
	timer                 uint8
}

func newDhcpTransactionInfo(timer uint8, smac string) dhcpTransactionInfo {
	var dt dhcpTransactionInfo
	dt.timer = timer
	dt.smac = smac
	return dt
}

func (dt *dhcpTransactionInfo) getTimer() uint8 {
	return dt.timer
}

func (dt *dhcpTransactionInfo) decrementTimer() uint8 {
	dt.timer--
	return dt.timer
}

func (dt *dhcpTransactionInfo) getPendingRequestCount() uint32 {
	return dt.pendingRequestCount
}

func (dt *dhcpTransactionInfo) incrementPendingRequestCount() {
	dt.pendingRequestCount++
}

func (dt *dhcpTransactionInfo) getReceivedResponseCount() uint32 {
	return dt.receivedResponseCount
}

func (dt *dhcpTransactionInfo) responseReceived() {
	dt.receivedResponseCount++
	dt.pendingRequestCount--
}

func (dt *dhcpTransactionInfo) resetRequestResponseCount(timer uint8) {
	if dt.pendingRequestCount >= dt.previousRequestCount {
		dt.pendingRequestCount = dt.pendingRequestCount - dt.previousRequestCount
	}
	dt.previousRequestCount = dt.pendingRequestCount
	dt.receivedResponseCount = 0
	dt.timer = timer
}

// alarmsRaisedInfo contains the all networks alarm raised information
type alarmsRaisedInfo struct {
	arrayInfo []dhcpServerTag
}

// add an entry into alarm raised array
func (a *alarmsRaisedInfo) add(val dhcpServerTag) {
	a.arrayInfo = append(a.arrayInfo, val)
}

// isexist check if entry exist in alarm raised array
func (a *alarmsRaisedInfo) isexist(val dhcpServerTag) bool {
	for _, srvTag := range a.arrayInfo {
		if srvTag == val {
			return true
		}
	}
	return false
}

// remove deletes given entry from alarm raised array
func (a *alarmsRaisedInfo) remove(val dhcpServerTag) {
	for ind := range a.arrayInfo {
		if a.arrayInfo[ind] == val {
			a.arrayInfo = append(a.arrayInfo[:ind], a.arrayInfo[ind+1:]...)
			break
		}
	}
}
