package app

import (
	"log"
	"os"
	"time"

	"git.ego.freeddns.org/egommerce/go-api-pkg/fluentd"
	db "git.ego.freeddns.org/egommerce/identity-service/pkg/database"
	redis "github.com/go-redis/redis/v8"
)

type (
	Plugin struct {
		name string
		fn   PluginFn
	}
	PluginFn func() any
)

func CachePlugin(cArr map[string]string) Plugin {
	// fmt.Println(cArr["cacheAddr"], cArr["cacheUsername"], cArr["cachePassword"])
	return Plugin{
		name: "cache",
		fn: func() any { // FIXME: return type
			return redis.NewClient(&redis.Options{
				Addr:        cArr["cacheAddr"],
				Username:    cArr["cacheUsername"],
				Password:    cArr["cachePassword"],
				DB:          0,
				DialTimeout: 100 * time.Millisecond,
			})
		},
	}
}

func DatabasePlugin(cArr map[string]string) Plugin {
	return Plugin{
		name: "database",
		fn: func() any { // FIXME: return type
			dbConn, _ := db.Connect(cArr["dbURL"])
			// if err != nil {
			// 	log.Fatalf("Failed to connect to the Database: %s. Err: %v\n", cArr["dbURL"], err)
			// 	os.Exit(1)
			// }

			return dbConn
		},
	}
}

// func EventbusPlugin(cArr map[string]string) Plugin {
// 	return Plugin{
// 		name: "eventbus",
// 		fn: func() any { // FIXME: return type
// 			conn, err := amqp.Dial(cArr["eventBusURL"])
// 			if err != nil {
// 				log.Fatalf("Failed to connect to the EventBus: %s. Err: %v\n", cArr["eventBusURL"], err)
// 				os.Exit(1) // TODO: retry in background...
// 			}

// 			chn, err := conn.Channel()
// 			if err != nil {
// 				log.Fatalf("Failed to open new EventBus channel. Err: %v\n", err)
// 				os.Exit(1) // TODO: retry in background...
// 			}

// 			return chn
// 		},
// 	}
// }

func LoggerPlugin(cArr map[string]string) Plugin {
	return Plugin{
		name: "logger",
		fn: func() any { // FIXME: return type
			logHost, logPort, err := fluentd.ParseAddr(cArr["loggerAddr"])
			if err != nil {
				log.Fatalf("Failed to parse FluentD address: %s. Err: %v", cArr["loggerAddr"], err)
				os.Exit(1)
			}

			logger, err := fluentd.NewLogger(cArr["appFullname"], logHost, logPort)
			if err != nil {
				log.Fatalf("Failed to connect to the FluentD on %s:%d. Err: %v", logHost, logPort, err)
				os.Exit(1)
			}

			return logger
		},
	}
}
