package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"time"

	"github.com/gorilla/handlers"
	"github.com/jinzhu/gorm"
	"github.com/robfig/cron"

	"gogs.carducci-dante.gov.it/karmen/core/config"
	"gogs.carducci-dante.gov.it/karmen/core/cron/sync"
	"gogs.carducci-dante.gov.it/karmen/core/generator"
	"gogs.carducci-dante.gov.it/karmen/core/generator/generators/list"
	karmen_handlers "gogs.carducci-dante.gov.it/karmen/core/handlers"
	"gogs.carducci-dante.gov.it/karmen/core/orm"
)

const (
	MaxNumRetries     = 20
	RetryTimeInterval = 5
)

func main() {

	var (
		db  *gorm.DB
		err error
	)

	log.Println("Loading config file...")
	err = config.ReadFile("config/config.yaml", config.Config)
	if err != nil {
		panic(err)
	}

	log.Println("Starting karmen and waiting for the DB...")

	count := MaxNumRetries
	wait := true

	for wait && count > 0 {
		db, err = orm.New(fmt.Sprintf("%s?%s", config.Config.Orm.Connection, config.Config.Orm.Options))
		if err != nil {
			count--
			log.Println(err)
			log.Printf("Remaining retries: %d", count)
			time.Sleep(time.Second * RetryTimeInterval)
			continue
		}
		wait = false
	}

	orm.Use(db)

	if config.Config.Orm.AutoMigrate {
		log.Print("Automigrating...")
		orm.AutoMigrate()
	}

	log.Println("Initialize ListGenerator")

	generator.Generators = make(map[string]generator.Generator)
	generator.Generators["list"] = list.NewListGenerator(config.Config)

	log.Println("Starting cron jobs...")

	c := cron.New()

	syncJob := sync.NewSyncJob(config.Config)

	if config.Config.Sync.Schedule == "" {
		config.Config.Sync.Schedule = "@every 10m"
	}

	log.Printf("Adding LDAP Sync Job with schedule set at %s", config.Config.Sync.Schedule)
	log.Printf("Sync will run with SAFE mode set to %v", config.Config.Sync.SafeRun)
	log.Printf("Sync will run with SEND_MAIL set to %v", config.Config.Sync.SendMail)
	log.Printf("Sync will run with SCHEDULE set to %v", config.Config.Sync.Schedule)
	c.AddJob(config.Config.Sync.Schedule, syncJob)

	c.Start()

	log.Println("karmen is listening to port 3000...")
	if err := http.ListenAndServe(":3000", handlers.LoggingHandler(os.Stdout, karmen_handlers.Handlers())); err != nil {
		panic(err)
	}

}
