// TODO: Add EUPL banner everywhere
package main

import (
	"io"
	"os"
	"strings"

	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"gitlab.com/mstarongitlab/linstrom/ap"
	"gitlab.com/mstarongitlab/linstrom/config"
	"gitlab.com/mstarongitlab/linstrom/storage"
	"gitlab.com/mstarongitlab/linstrom/storage/cache"
)

func main() {
	setLogger()
	setLogLevel()
	if err := config.ReadAndWriteToGlobal(*flagConfigFile); err != nil {
		log.Fatal().
			Err(err).
			Str("config-file", *flagConfigFile).
			Msg("Failed to read config and couldn't write default")
	}
	res, err := ap.GetAccountWebfinger("@aufricus_athudath@activitypub.academy")
	log.Info().
		Err(err).
		Any("webfinger", res).
		Msg("Webfinger request result for @aufricus_athudath@activitypub.academy")
	storageCache, err := cache.NewCache(
		config.GlobalConfig.Storage.MaxInMemoryCacheSize,
		config.GlobalConfig.Storage.RedisUrl,
	)
	if err != nil {
		log.Fatal().Err(err).Msg("Failed to start cache")
	}

	// var store *storage.Storage
	// if config.GlobalConfig.Storage.DbIsPostgres != nil && *config.GlobalConfig.Storage.DbIsPostgres {
	// 	store, err = storage.NewStoragePostgres(config.GlobalConfig.Storage.DatabaseUrl, storageCache)
	// } else {
	// 	store, err = storage.NewStorageSqlite(config.GlobalConfig.Storage.DatabaseUrl, storageCache)
	// }
	//
	store, err := storage.NewStorage(config.GlobalConfig.Storage.BuildPostgresDSN(), storageCache)

	if err != nil {
		log.Fatal().Err(err).Msg("Failed to setup storage")
	}
	_ = store
	// TODO: Set up media server
	// TODO: Set up queues
	// TODO: Set up http server
	// TODO: Set up plugins
	// TODO: Start everything
}

func setLogLevel() {
	log.Info().Str("new-level", *flagLogLevel).Msg("Attempting to set log level")
	switch strings.ToLower(*flagLogLevel) {
	case "trace":
		zerolog.SetGlobalLevel(zerolog.TraceLevel)
	case "debug":
		zerolog.SetGlobalLevel(zerolog.DebugLevel)
	case "info":
		zerolog.SetGlobalLevel(zerolog.InfoLevel)
	case "warn":
		zerolog.SetGlobalLevel(zerolog.WarnLevel)
	case "error":
		zerolog.SetGlobalLevel(zerolog.ErrorLevel)
	case "fatal":
		zerolog.SetGlobalLevel(zerolog.FatalLevel)
	default:
		zerolog.SetGlobalLevel(zerolog.InfoLevel)
	}
}

func setLogger(extraLogWriters ...io.Writer) {
	if *flagPrettyPrint {
		console := zerolog.ConsoleWriter{Out: os.Stderr}
		log.Logger = zerolog.New(zerolog.MultiLevelWriter(append([]io.Writer{console}, extraLogWriters...)...)).
			With().
			Timestamp().
			Logger()
	} else {
		log.Logger = zerolog.New(zerolog.MultiLevelWriter(
			append([]io.Writer{log.Logger}, extraLogWriters...)...,
		)).With().Timestamp().Logger()
	}
}
