package main

import (
	"fmt"
	"intent-system/pkg/api"
	"intent-system/pkg/config"
	"intent-system/pkg/itypes"
	"intent-system/pkg/services"
	"os"
	"os/signal"

	"github.com/civet148/log"
	"github.com/urfave/cli/v2"
)

const (
	Version     = "v0.5.11"
	ProgramName = "intent-system"
)

var (
	BuildTime = "2024-05-11"
	GitCommit = ""
)

const (
	CMD_NAME_RUN   = "run"
	CMD_NAME_START = "start"
)

const (
	CMD_FLAG_NAME_DSN            = "dsn"
	CMD_FLAG_NAME_POSTGRESQL     = "pg"
	CMD_FLAG_NAME_DEBUG          = "debug"
	CMD_FLAG_NAME_STATIC         = "static"
	CMD_FLAG_NAME_DOMAIN         = "domain"
	CMD_FLAG_NAME_IMAGE_PATH     = "image-path"
	CMD_FLAG_NAME_IMAGE_PREFIX   = "image-prefix"
	CMD_FLAG_NAME_GATEWAY_URL    = "gateway-url"
	CMD_FLAG_NAME_GATEWAY_KEY    = "gateway-key"
	CMD_FLAG_NAME_GATEWAY_SECRET = "gateway-secret"
	CMD_FLAG_NAME_SUB_CRON       = "sub-cron"
)

var manager api.ManagerApi

func init() {
}

func grace() {
	//capture signal of Ctrl+C and gracefully exit
	sigChannel := make(chan os.Signal, 1)
	signal.Notify(sigChannel, os.Interrupt)
	go func() {
		for {
			select {
			case s := <-sigChannel:
				{
					if s != nil && s == os.Interrupt {
						fmt.Printf("Ctrl+C signal captured, program exiting...\n")
						if manager != nil {
							manager.Close()
						}
						close(sigChannel)
						os.Exit(0)
					}
				}
			}
		}
	}()
}

func main() {

	grace()

	local := []*cli.Command{
		runCmd,
	}
	app := &cli.App{
		Name:     ProgramName,
		Version:  fmt.Sprintf("%s %s commit %s", Version, BuildTime, GitCommit),
		Flags:    []cli.Flag{},
		Commands: local,
		Action:   nil,
	}
	if err := app.Run(os.Args); err != nil {
		log.Errorf("exit in error %s", err)
		os.Exit(1)
		return
	}
}

var runCmd = &cli.Command{
	Name:      CMD_NAME_RUN,
	Usage:     "run as a web service",
	ArgsUsage: "[listen address]",
	Aliases:   []string{CMD_NAME_START},
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:  CMD_FLAG_NAME_DEBUG,
			Usage: "open debug log mode",
		},
		&cli.StringFlag{
			Name:    CMD_FLAG_NAME_DSN,
			Usage:   "data source name of database",
			Value:   itypes.DEFAULT_DATA_SOURCE_NAME,
			Aliases: []string{"n"},
		},
		//&cli.StringFlag{
		//	Name:  CMD_FLAG_NAME_STATIC,
		//	Usage: "frontend static path",
		//	Value: itypes.DefaultStaticHome,
		//},
		&cli.StringFlag{
			Name:    CMD_FLAG_NAME_IMAGE_PATH,
			Usage:   "image saving path",
			Value:   itypes.DefaultImagesHome,
			Aliases: []string{"i"},
		},
		&cli.StringFlag{
			Name:     CMD_FLAG_NAME_DOMAIN,
			Usage:    "domain url",
			Required: true,
			Aliases:  []string{"d"},
		},
		&cli.StringFlag{
			Name:    CMD_FLAG_NAME_IMAGE_PREFIX,
			Usage:   "image url prefix",
			Value:   itypes.DEFAULT_IMAGE_PREFIX,
			Aliases: []string{"p"},
		},
		&cli.StringFlag{
			Name:     CMD_FLAG_NAME_GATEWAY_URL,
			Usage:    "sdk gateway url",
			Aliases:  []string{"g"},
			Required: true,
		},
		&cli.StringFlag{
			Name:     CMD_FLAG_NAME_GATEWAY_KEY,
			Usage:    "sdk gateway access key",
			Aliases:  []string{"k"},
			Required: true,
		}, &cli.StringFlag{
			Name:     CMD_FLAG_NAME_GATEWAY_SECRET,
			Usage:    "sdk gateway access secret",
			Aliases:  []string{"s"},
			Required: true,
		},
		&cli.StringFlag{
			Name:     CMD_FLAG_NAME_POSTGRESQL,
			Usage:    "Postgresql connection string for news sync",
			Required: true,
		},

		&cli.StringFlag{
			Name:  CMD_FLAG_NAME_SUB_CRON,
			Usage: "cron task for email subscription",
			Value: itypes.DEFAULT_SUB_CRON_EMAIL_PUSH,
		},
	},
	Action: func(cctx *cli.Context) error {
		cfg := &config.Config{
			Version:       Version,
			HttpAddr:      itypes.DEFAULT_HTTP_LISTEN_ADDR,
			DSN:           cctx.String(CMD_FLAG_NAME_DSN),
			Debug:         cctx.Bool(CMD_FLAG_NAME_DEBUG),
			Domain:        cctx.String(CMD_FLAG_NAME_DOMAIN),
			Static:        cctx.String(CMD_FLAG_NAME_STATIC),
			ImagePath:     cctx.String(CMD_FLAG_NAME_IMAGE_PATH),
			ImagePrefix:   cctx.String(CMD_FLAG_NAME_IMAGE_PREFIX),
			GatewayUrl:    cctx.String(CMD_FLAG_NAME_GATEWAY_URL),
			GatewayKey:    cctx.String(CMD_FLAG_NAME_GATEWAY_KEY),
			GatewaySecret: cctx.String(CMD_FLAG_NAME_GATEWAY_SECRET),
			Postgresql:    cctx.String(CMD_FLAG_NAME_POSTGRESQL),
			SubCron:       cctx.String(CMD_FLAG_NAME_SUB_CRON),
		}

		cfg.Version = Version
		if cfg.Debug {
			log.SetLevel("debug")
		}
		log.Json("configuration", cfg)
		if cctx.Args().First() != "" {
			cfg.HttpAddr = cctx.Args().First()
		}
		if err := cfg.Save(); err != nil {
			return err
		}
		//start up as a web server
		manager = services.NewManager(cfg)
		return manager.Run()
	},
}
