package main

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

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

	"gogs.carducci-dante.gov.it/karmen/config"
	"gogs.carducci-dante.gov.it/karmen/core/api"
	"gogs.carducci-dante.gov.it/karmen/core/orm"
	"gogs.carducci-dante.gov.it/karmen/core/renderer"
)

const (
	MaxNumRetries     = 20
	RetryTimeInterval = 2
)

func regenerateRelations(db *gorm.DB) error {
	var activities []orm.Activity

	if err := db.Find(&activities).Error; err != nil {
		return err
	}

	defer func() {
		if err := recover(); err != nil {
			log.Print(err)
		}
	}()

	for _, a := range activities {
		err := db.Save(&a).Error
		if err != nil {
			panic(err)
		}
	}

	return nil
}

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.Reset {
		log.Print("Resetting the DB...")
		orm.Reset()
	}

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

	if config.Config.Orm.Regenerate {
		log.Print("Regenerate relations...")
		if err := regenerateRelations(db); err != nil {
			panic(err)
		}
	}

	rend, err := renderer.NewHTMLRenderer("templates/")
	if err != nil {
		panic(err)
	}

	renderer.Use(rend)

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