package db

import (
	"io/ioutil"
	"olympus/oncall/backend/pkg/log"

	"github.com/spf13/viper"
	"gopkg.in/yaml.v2"
)

// This function is called every time some one wants to view the schedule.
//
// If some category needs to be updated, the the category will generate the next round's schedule.
func MayUpdateNextRound() error {
	categories, err := GetAllCategoriesWithName()
	if err != nil {
		log.Error("msg", "error: get all categories when may update", "error info", err)
		return err
	}
	currentWeek, err := GetTempWeekId()
	if err != nil {
		return err
	}
	for categoryId := range categories {
		categoryInf, err := GetCategoryInfo(categoryId)
		if err != nil {
			return err
		}
		if currentWeek >= categoryInf.NextRound {
			log.Info("msg", "update schedule for category", "category id", categoryId, "category name", categoryInf.Name)
			err = SetNewRound(categoryId, int(categoryInf.NextRound))
			if err != nil {
				return err
			}

			err = GenerateNextRoundByConfig(categoryId)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// Set new `this_round` and `next_round`
// for some category.
func SetNewRound(categoryId int, oldNextRound int) error {
	content, err := ioutil.ReadFile(viper.GetViper().GetString("round-path"))
	if err != nil {
		log.Error("msg", "fail to load round file")
	}
	round := &Round{}

	err = yaml.Unmarshal(content, round)
	if err != nil {
		log.Error("msg", "fail to unmarshal round file")
	}
	var shift Shift
	for _, v := range round.Shifts {
		if v.Category == categoryId {
			shift = *v
			break
		}
	}
	if shift.Category == 0 {
		log.Error("msg", "cannot find category robin information", "category id", categoryId)
		return nil
	}
	categoryInf, err := GetCategoryInfo(categoryId)
	if err != nil {
		return err
	}
	totalWeek := len(shift.Robin) * categoryInf.Period
	const SET_NEXT_ROUND = `
		update
			categories
		set
			next_round = ?
		where
			category_id = ?`
	GetDB().Exec(SET_NEXT_ROUND, totalWeek+oldNextRound, categoryId)
	const SET_THIS_ROUND = `
		update
			categories
		set
			this_round = ?
		where
			category_id = ?`
	GetDB().Exec(SET_THIS_ROUND, oldNextRound, categoryId)
	return nil
}
