package main import ( "context" "fmt" "log" "net/smtp" "os" "os/signal" "strings" "syscall" "time" "gitea.urkob.com/urko/btc-pay-checker/internal/api" "gitea.urkob.com/urko/btc-pay-checker/internal/platform/mongodb/order" "gitea.urkob.com/urko/btc-pay-checker/internal/services" "gitea.urkob.com/urko/btc-pay-checker/internal/services/btc" "gitea.urkob.com/urko/btc-pay-checker/internal/services/mail" "gitea.urkob.com/urko/btc-pay-checker/internal/services/price" "gitea.urkob.com/urko/btc-pay-checker/kit/cfg" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { envFile := "" if os.Getenv("PAY_CHECKER_ENV") == "dev" { envFile = ".env" } config := cfg.NewConfig(envFile) log.SetFlags(log.Lmicroseconds) if config.LogFile { logFileName := fmt.Sprintf("%s.txt", time.Now().Format(strings.ReplaceAll(time.RFC1123Z, ":", "_"))) f, err := os.OpenFile(logFileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o644) if err != nil { log.Fatal(err) } defer f.Close() log.SetOutput(f) } dbOpts := options.Client() dbOpts.ApplyURI(config.DbAddress) ctx, cancel := context.WithCancel(signalContext(context.Background())) defer cancel() client, err := mongo.Connect(ctx, dbOpts) if err != nil { panic(fmt.Errorf("mongo.NewClient: %w", err)) } log.Println("mongodb client is connected") ordersCollection := client. Database(config.DbName). Collection(config.OrdersCollection) orderRepo := order.NewRepo(ordersCollection) orderSrv := services.NewOrder(orderRepo) priceSrv := price.NewPriceConversor(config.ConversorApi, config.ConversorApi) btcSrv := btc.NewBitcoinService(config.RpcHost, config.RpcAuth, config.RpcZmq, config.WalletAddress).WithTestnet() mailSrv := mail.NewMailService( mail.MailServiceConfig{ Auth: smtp.PlainAuth("", config.MailUser, config.MailPassword, config.MailHost), Host: config.MailHost, Port: config.MailPort, From: config.MailFrom, TemplatesDir: config.MailTemplatesDir, }, ) restServer := api.NewRestServer(config, orderSrv, btcSrv, priceSrv, mailSrv) go func() { if err = restServer.Start(ctx, config.ApiPort, config.Views); err != nil { panic(fmt.Errorf("restServer.Start: %w", err)) } }() <-ctx.Done() if restServer != nil { if err := restServer.Shutdown(); err != nil { panic(fmt.Errorf("restServer.Shutdown: %w", err)) } } log.Println("gracefully shutdown") } func signalContext(ctx context.Context) context.Context { ctx, cancel := context.WithCancel(ctx) sigs := make(chan os.Signal, 1) signal.Notify(sigs, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) go func() { log.Println("listening for shutdown signal") <-sigs log.Println("shutdown signal received") signal.Stop(sigs) close(sigs) cancel() }() return ctx }