package main
import (
"context"
"fmt"
"log"
"net/http"
"donetick.com/core/config"
"donetick.com/core/frontend"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"go.uber.org/fx"
"go.uber.org/zap/zapcore"
"gorm.io/gorm"
auth "donetick.com/core/internal/authorization"
"donetick.com/core/internal/chore"
chRepo "donetick.com/core/internal/chore/repo"
"donetick.com/core/internal/circle"
cRepo "donetick.com/core/internal/circle/repo"
"donetick.com/core/internal/database"
"donetick.com/core/internal/email"
notifier "donetick.com/core/internal/notifier"
nRepo "donetick.com/core/internal/notifier/repo"
nps "donetick.com/core/internal/notifier/service"
telegram "donetick.com/core/internal/notifier/telegram"
"donetick.com/core/internal/thing"
tRepo "donetick.com/core/internal/thing/repo"
"donetick.com/core/internal/user"
uRepo "donetick.com/core/internal/user/repo"
"donetick.com/core/internal/utils"
"donetick.com/core/logging"
"donetick.com/core/migration"
)
func main() {
logging.SetConfig(&logging.Config{
Encoding: "console",
Level: zapcore.Level(zapcore.DebugLevel),
Development: true,
})
app := fx.New(
fx.Supply(config.LoadConfig()),
fx.Supply(logging.DefaultLogger().Desugar()),
// fx.Provide(config.NewConfig),
fx.Provide(auth.NewAuthMiddleware),
// fx.Provide(NewBot),
fx.Provide(database.NewDatabase),
fx.Provide(chRepo.NewChoreRepository),
fx.Provide(chore.NewHandler),
fx.Provide(uRepo.NewUserRepository),
fx.Provide(user.NewHandler),
fx.Provide(cRepo.NewCircleRepository),
fx.Provide(circle.NewHandler),
fx.Provide(nRepo.NewNotificationRepository),
fx.Provide(nps.NewNotificationPlanner),
// add notifier
fx.Provide(telegram.NewTelegramNotifier),
// Rate limiter
fx.Provide(utils.NewRateLimiter),
// add email sender:
fx.Provide(email.NewEmailSender),
// add handlers also
fx.Provide(newServer),
fx.Provide(notifier.NewScheduler),
// things
fx.Provide(tRepo.NewThingRepository),
fx.Provide(thing.NewWebhook),
fx.Provide(thing.NewHandler),
fx.Provide(frontend.NewHandler),
// fx.Invoke(RunApp),
fx.Invoke(
chore.Routes,
user.Routes,
circle.Routes,
thing.Routes,
thing.Webhooks,
frontend.Routes,
func(r *gin.Engine) {},
),
)
if err := app.Err(); err != nil {
log.Fatal(err)
}
app.Run()
}
func newServer(lc fx.Lifecycle, cfg *config.Config, db *gorm.DB, notifier *notifier.Scheduler) *gin.Engine {
gin.SetMode(gin.DebugMode)
// log when http request is made:
r := gin.New()
srv := &http.Server{
Addr: fmt.Sprintf(":%d", cfg.Server.Port),
Handler: r,
ReadTimeout: cfg.Server.ReadTimeout,
WriteTimeout: cfg.Server.WriteTimeout,
}
config := cors.DefaultConfig()
if cfg.IsDoneTickDotCom {
config.AllowOrigins = cfg.Server.CorsAllowOrigins
} else {
config.AllowAllOrigins = true
}
config.AllowCredentials = true
config.AddAllowHeaders("Authorization", "secretkey")
r.Use(cors.New(config))
lc.Append(fx.Hook{
OnStart: func(context.Context) error {
if cfg.Database.Migration {
migration.Migration(db)
}
notifier.Start(context.Background())
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
return nil
},
OnStop: func(context.Context) error {
if err := srv.Shutdown(context.Background()); err != nil {
log.Fatalf("Server Shutdown: %s", err)
}
return nil
},
})
return r
}