package main

import (
	"flag"
	"fmt"

	"git.gocasts.ir/ebhomengo/niki/adapter/kavenegar"
	"git.gocasts.ir/ebhomengo/niki/adapter/redis"
	"git.gocasts.ir/ebhomengo/niki/config"
	smscontract "git.gocasts.ir/ebhomengo/niki/contract/sms"
	httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server"
	"git.gocasts.ir/ebhomengo/niki/repository/migrator"
	"git.gocasts.ir/ebhomengo/niki/repository/mysql"
	"git.gocasts.ir/ebhomengo/niki/service"
	_ "github.com/go-sql-driver/mysql"
)

// @securityDefinitions.apikey AuthBearerBenefactor
// @in header
// @name Authorization
// @description Type the word 'Bearer' followed by a space and Benefactor JWT token
// @securityDefinitions.apikey  AuthBearerAdmin
// @in header
// @name Authorization
// @description Type the word 'Bearer' followed by a space and Admin JWT token.
func main() {
	cfg := Config()
	db := MariaDB(cfg)
	defer func() {
		if err := db.CloseStatements(); err != nil {
			fmt.Printf("Error closing statements: %v\n", err)
		}
	}()
	rds := Redis(cfg)
	kvn := Kavenegar(cfg)
	svc := Service(cfg, db, rds, kvn)
	httpServer := HTTPServer(cfg, svc)
	httpServer.Serve()
}

func Config() config.Config {
	return config.C()
}

func MariaDB(cfg config.Config) *mysql.DB {
	migrate := flag.Bool("migrate", false, "perform mysql migration")
	flag.Parse()
	if *migrate {
		migrator.New(migrator.Config{
			MysqlConfig:     cfg.Mysql,
			MigrationPath:   "./repository/mysql/migrations",
			MigrationDBName: "gorp_migrations",
		}).Up()
	}

	return mysql.New(cfg.Mysql)
}

func Redis(cfg config.Config) *redis.Adapter {
	return redis.New(cfg.Redis)
}

func Kavenegar(cfg config.Config) *kavenegar.Adapter {
	return kavenegar.New(cfg.KavenegarSmsProvider)
}

func Service(cfg config.Config, db *mysql.DB, rds *redis.Adapter, smsAdapter smscontract.SmsAdapter) *service.Service {
	return service.New(cfg, db, rds, smsAdapter)
}

func HTTPServer(cfg config.Config, svc *service.Service) *httpserver.Server {
	return httpserver.New(cfg, svc)
}
