package main

import (
	"errors"
	"fmt"
	"log"
	"os"

	"github.com/gin-gonic/gin"
	"github.com/joho/godotenv"
	"gorm.io/driver/postgres"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"stereo.cat/backend/internal/api"
	"stereo.cat/backend/internal/auth"
	"stereo.cat/backend/internal/auth/client"
	"stereo.cat/backend/internal/types"
)

func getEnv(key, fallback string) string {
	if value, ok := os.LookupEnv(key); ok {
		return value
	}
	return fallback
}

func requireEnv(key string) string {
	if value, ok := os.LookupEnv(key); ok {
		return value
	}
	panic(errors.New(fmt.Sprintf("Environment variable %s is required but not specified. Exiting...", key)))
}

func main() {
	_ = godotenv.Load()

	databaseType := getEnv("DATABASE_TYPE", "sqlite")
	sqliteFile := getEnv("SQLITE_FILE", "stereo.db")
	imagePath := getEnv("IMAGE_PATH", os.TempDir())

	if _, err := os.Stat(imagePath); err != nil {
		if os.IsNotExist(err) {
			if err := os.MkdirAll(imagePath, os.ModePerm); err != nil {
				log.Fatal(err)
			}
		}
	}

	c := types.StereoConfig{
		Router:    gin.Default(),
		ImagePath: imagePath,
		Client: client.New(
			requireEnv("REDIRECT_URI"),
			requireEnv("CLIENT_ID"),
			requireEnv("CLIENT_SECRET"),
		),
		JWTSecret: requireEnv("JWT_SECRET"),
	}

	switch databaseType {
	case "sqlite":
		db, err := gorm.Open(sqlite.Open(sqliteFile), &gorm.Config{})

		c.Database = db

		if err != nil {
			panic(err)
		}

		break

	case "postgres":
		db, err := gorm.Open(postgres.Open(requireEnv("POSTGRES_DSN")), &gorm.Config{})

		c.Database = db

		if err != nil {
			panic(err)
		}

		break
	default:
		panic(errors.New("Invalid database type was specified."))
	}

	c.Database.AutoMigrate(&auth.User{}, &types.File{})

	api.Register(&c)
	fmt.Printf("Running on port %s\n", getEnv("PORT", "8080"))
	c.Router.Run()
}