package main

import (
	"fmt"
	"log"
	"os"

	"github.com/deranjer/gvc/common"
	"github.com/deranjer/gvc/common/database"
	serverEngine "github.com/deranjer/gvc/server/engine"
	serverconfig "github.com/deranjer/gvc/server/serverconfig"
	"github.com/deranjer/store"
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
	"github.com/rs/zerolog"
)

var version = "0.1"

func main() {
	// Initialize a new server struct and config struct
	var err error
	var configPath string
	var conf serverconfig.GvcServerConfig
	configPath, err = serverconfig.FindConfig()
	if err != nil {
		fmt.Printf("Unable to find config file: %s\n", err)
		fmt.Println("Since no config found, creating a default config to use...")
		conf = serverconfig.GvcServerConfig{
			LogFile:          "gvclog.log",
			LogLevel:         2,
			Version:          "0.1",
			Port:             80,
			RepoRootPath:     "repos",  //default repos directory will be cwd\repos
			DatabaseLocation: "gvc.db", //database is stored in root dir by default
		}
		configPath = serverconfig.DefaultConfigPath             // set the root path for our config so we can save that back to TOML
		err = store.Save(serverconfig.DefaultConfigPath, &conf) // Save our new default config back to TOML so it can be read in
		if err != nil {
			log.Fatalf("unable to save config to toml file: %s", err)
		}
	}
	err = store.Load(configPath, &conf) // existing conf was found or default conf created, so reading it in
	if err != nil {
		log.Fatalf("Error loading server config file into struct, please fix config, panic! \n%s", err)
	}
	err = serverconfig.ValidateConfig(&conf, configPath, version) // now that our config has been loaded, lets make sure it is valid
	if err != nil {
		log.Fatalf("unable to validate config, exiting: %s", err)
	}
	// Setup a new server instance
	var server serverEngine.GVCServer
	server.Config = conf
	fmt.Println("Attempting to start logger...")
	// Setting up the logger to file output
	logFile, err := os.OpenFile(conf.LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalf("unable to open log file at: %s, exiting with error: %s", conf.LogFile, err)
	}
	defer logFile.Close()
	// Setup non-http logging (using middleware for Echo http logging)
	logLevel, err := common.SetLogLevel(conf.LogLevel)
	if err != nil {
		fmt.Println("invalid log level set in config, setting to info")
	}
	serverlog := zerolog.New(logFile)
	serverlog.WithLevel(logLevel)
	// Check/Setup the database
	database.OpenOrCreateDB(conf.DatabaseLocation, &serverlog)
	// Setup the web server
	e := echo.New()
	// Setup the logger to print to the file specified in config
	e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
		Output: logFile,
	}))
	e.Logger.Info("echo logger has started")
	server.Echo = e
	//Start the routes
	//e.GET("/hello", server.Hello)
	e.GET("/info/:repo", server.GetInfo)
	e.GET("/lock/:repo/:type/:name", server.LockFile)
	e.GET("/refresh/:repo", server.Refresh)
	e.GET("/revert/:repo/:hash", server.Revert) // TODO: Might not need this, just add extra args to pull?
	e.GET("/pull/:repo/:branch", server.Pull)
	e.Logger.Fatal(e.Start(fmt.Sprintf("%s:%d", server.Config.BindIP, server.Config.Port)))
}
