package app

import (
	"context"
	"net/http"

	"github.com/AlchemyTelcoSolutions/callisto-so-bff/cmd/app/config"
	commonDomain "github.com/AlchemyTelcoSolutions/utils/service/domain"
	"github.com/AlchemyTelcoSolutions/xutils-go/xlogger"
	"golang.org/x/sync/errgroup"
)

func NewApp(cfg config.AppConfig, logger xlogger.Logger) *App {
	return &App{
		config: cfg,
		logger: logger,
	}
}

func (a *App) SetClients(c *Clients) *App {
	a.clients = c
	return a
}

func (a *App) InitClients(ctx context.Context) error {
	err := a.initClients(ctx)
	if err != nil {
		return commonDomain.Wrap(err, "failed to setup required external clients")
	}

	return nil
}

func (a *App) Run(ctx context.Context) error {
	errGrp, ctxGrp := errgroup.WithContext(ctx)

	httpServer, err := a.initHTTPServer(ctxGrp)
	if err != nil {
		return commonDomain.Wrap(err, "failed to setup http server")
	}

	errGrp.Go(func() error {
		defer a.logger.Info("http server stopped")

		a.logger.Info("http server started")
		err = httpServer.ListenAndServe()
		if err != nil && err != http.ErrServerClosed {
			return commonDomain.Wrap(err, "http server stopped with error")
		}
		return nil
	})

	errGrp.Go(func() error {
		<-ctxGrp.Done()
		if err = httpServer.Shutdown(context.Background()); err != nil {
			a.logger.Error("error shutting server down", err)
		}

		return ctxGrp.Err()
	})

	a.logger.Info("app started")

	return errGrp.Wait()
}
