package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"github.com/tidbcloud/pov-service/internal/config"
	"github.com/tidbcloud/pov-service/internal/dep"
	"github.com/tidbcloud/pov-service/internal/handler"
	"github.com/tidbcloud/pov-service/internal/pkg/log"
	"github.com/tidbcloud/pov-service/internal/service"
	"github.com/robfig/cron"

	_ "github.com/tidbcloud/pov-service/docs" // docs is generated by Swag CLI, you have to import it.
	// echo-swagger middleware
)

var (
	version    = "latest"
	buildTime  = "none"
	configPath = flag.String("config", "", "specify the config path")
	secretPath = flag.String("secret", "", "specify the secret config directory")
)

func waitShutdown(d *dep.Deps) {
	shutdown := make(chan os.Signal, 1)
	signal.Notify(shutdown, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
	<-shutdown
	_ = d.Container.Invoke(func(m *handler.Manager) error {
		m.Shutdown()
		return nil
	})
}

func setupDeps(c *config.Config) (*dep.Deps, error) {
	logger := log.Log
	deps := dep.NewDeps()
	if err := deps.Init(c, *logger); err != nil {
		return nil, err
	}

	return deps, nil
}

func main() {
	log.Log.Infof("version: %s, build time: %s", version, buildTime)

	flag.Parse()
	conf := config.New(*configPath, *secretPath)

	// Setup di dependencies
	deps, err := setupDeps(conf)
	if err != nil {
		panic(err)
	}

	// Start http server
	if err := deps.Container.Invoke(func(m *handler.Manager) error {
		if m.Register() != nil {
			return err
		}

		m.Start()
		return nil
	}); err != nil {
		fmt.Println(err)
		panic(err)
	}

	// Start runnable services
	if err := deps.Container.Invoke(func(c *cron.Cron) {
		c.Start()
	}); err != nil {
		panic(err)
	}
	if err := deps.Container.Invoke(func(m *service.Manager) error {
		log.Log.Infof("start to run runable svcs for count %d", len(m.Runnables))
		go func() {
			err := m.Run(context.Background())
			if err != nil {
				panic(err)
			}
		}()
		return nil

	}); err != nil {
		panic(err)
	}

	waitShutdown(deps)
}
