//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
//Copyright (C) 2024 HTWKalender support@htwkalender.de

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU Affero General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU Affero General Public License for more details.

//You should have received a copy of the GNU Affero General Public License
//along with this program.  If not, see <https://www.gnu.org/licenses/>.

package service

import (
	"htwkalender/data-manager/model/serviceModel"
	"htwkalender/data-manager/service/course"
	"htwkalender/data-manager/service/feed"
	"htwkalender/data-manager/service/fetch/sport"
	v1 "htwkalender/data-manager/service/fetch/v1"
	v2 "htwkalender/data-manager/service/fetch/v2"
	"htwkalender/data-manager/service/functions/time"
	"log/slog"
	"strconv"
)

func AddSchedules(services serviceModel.Service) {

	services.App.Cron().MustAdd("updateCourses", "0 22 * * 0", func() {
		slog.Info("Started updating courses schedule")
		groups, err := v1.FetchSeminarGroups(services.App)
		if err != nil {
			slog.Warn("Failed to fetch seminar groups: ", "error", err)
		}
		slog.Info("Successfully fetched " + strconv.FormatInt(int64(len(groups)), 10) + " seminar groups")
	})

	// Every day at 5am and 5pm update all courses (5 segments - minute, hour, day, month, weekday) "0 5,17 * * *"
	// In Germany it is 7am and 7pm, syllabus gets updated twice a day at German 5:00 Uhr and 17:00 Uhr
	services.App.Cron().MustAdd("updateEventsByCourse", "0 5,17 * * *", func() {
		slog.Info("Started updating courses schedule")
		clock := time.RealClock{}
		course.UpdateCourse(services, clock)
	})

	// Every sunday at 1am clean all courses (5 segments - minute, hour, day, month, weekday) "0 3 * * 0"
	services.App.Cron().MustAdd("cleanFeeds", "0 1 * * 0", func() {
		// clean feeds older than 6 months
		slog.Info("Started cleaning feeds schedule")
		feed.ClearFeeds(services.App, 6, time.RealClock{})
	})

	// Every sunday at 3am fetch all sport events (5 segments - minute, hour, day, month, weekday) "0 2 * * 0"
	services.App.Cron().MustAdd("fetchSportEvents", "0 3 * * 0", func() {
		slog.Info("Started fetching sport events schedule")
		sportEvents, err := sport.FetchAndUpdateSportEvents(services.App)
		if err != nil {
			slog.Error("Failed to fetch and save sport events:", "error", err)
		}
		slog.Info("Successfully fetched " + strconv.FormatInt(int64(len(sportEvents)), 10) + " sport events")
	})

	//fetch all events for semester and delete  from remote this should be done every sunday at 2am
	services.App.Cron().MustAdd("fetchEvents", "0 22 * * 6", func() {
		savedEvents, err := v2.FetchAllEventsAndSave(services.App, time.RealClock{})
		if err != nil {
			slog.Error("Failed to fetch and save events: ", "error", err)
		} else {
			slog.Info("Successfully fetched " + strconv.FormatInt(int64(len(savedEvents)), 10) + " events")
		}
	})
}
