package scanner

import (
	"log"
	"sync"
	"time"

	"github.com/photoview/photoview/api/graphql/models"
	"gorm.io/gorm"
)

type periodicScanner struct {
	ticker         *time.Ticker
	ticker_changed chan bool
	mutex          *sync.Mutex
	db             *gorm.DB
}

var mainPeriodicScanner *periodicScanner = nil

func getPeriodicScanInterval(db *gorm.DB) (time.Duration, error) {

	var siteInfo models.SiteInfo
	if err := db.First(&siteInfo).Error; err != nil {
		return 0, err
	}

	return time.Duration(siteInfo.PeriodicScanInterval) * time.Second, nil
}

func InitializePeriodicScanner(db *gorm.DB) error {
	if mainPeriodicScanner != nil {
		panic("periodic scanner has already been initialized")
	}

	scanInterval, err := getPeriodicScanInterval(db)
	if err != nil {
		return err
	}

	mainPeriodicScanner = &periodicScanner{
		db:             db,
		ticker_changed: make(chan bool),
		mutex:          &sync.Mutex{},
	}

	go scanIntervalRunner()

	ChangePeriodicScanInterval(scanInterval)
	return nil
}

func ChangePeriodicScanInterval(duration time.Duration) {
	var new_ticker *time.Ticker = nil
	if duration > 0 {
		new_ticker = time.NewTicker(duration)
		log.Printf("Periodic scan interval changed: %s", duration.String())
	} else {
		log.Print("Periodic scan interval changed: disabled")
	}

	{
		mainPeriodicScanner.mutex.Lock()
		defer mainPeriodicScanner.mutex.Unlock()

		if mainPeriodicScanner.ticker != nil {
			mainPeriodicScanner.ticker.Stop()
		}

		mainPeriodicScanner.ticker = new_ticker
		mainPeriodicScanner.ticker_changed <- true
	}
}

func scanIntervalRunner() {
	for {
		log.Print("Scan interval runner: Waiting for signal")
		if mainPeriodicScanner.ticker != nil {
			select {
			case <-mainPeriodicScanner.ticker_changed:
				log.Print("Scan interval runner: New ticker detected")
			case <-mainPeriodicScanner.ticker.C:
				log.Print("Scan interval runner: Starting periodic scan")
				AddAllToQueue()
			}
		} else {
			<-mainPeriodicScanner.ticker_changed
			log.Print("Scan interval runner: New ticker detected")
		}
	}
}
