/*
* 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 (
	"context"
	"time"
)

// TimerType - type of timer used
type TimerType string

const (
	tickTimer        TimerType = "TickTimer"
	pendingPoolTimer TimerType = "PendingPoolTimer"
)

var timerMap = map[TimerType]bool{
	tickTimer:        false,
	pendingPoolTimer: false,
}

var timerChannels = make(map[TimerType](chan bool))

// TimerCfg structure
type TimerCfg struct {
	tick time.Duration
}

// Start to start timer
func (va *VoltApplication) Start(cntx context.Context, cfg TimerCfg, timerType TimerType) {
	if timerMap[timerType] {
		logger.Warn(ctx, "Duplicate Timer!!! Timer already running")
		return
	}
	timerMap[timerType] = true
	timerChannels[timerType] = make(chan bool)
	for {
		select {
		case <-time.After(cfg.tick):
			switch timerType {
			case tickTimer:
				va.Tick()
			case pendingPoolTimer:
				va.removeExpiredGroups(cntx)
			}
		case <-timerChannels[timerType]:
			return
		}
	}
}

// StopTimer to stop timers
func StopTimer() {
	for _, ch := range timerChannels {
		ch <- true
	}
}
