package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"gitea.ceperka.net/rosti/incus-sentinel/http_notifier"
	"gitea.ceperka.net/rosti/incus-sentinel/incus"
	"gitea.ceperka.net/rosti/incus-sentinel/scheduler"
	"github.com/urfave/cli/v3"
)

func main() {
	cmd := &cli.Command{
		Name:  "incus-sentinel",
		Usage: "Keeps an eye on sync and backups of Incus instances",
		Commands: []*cli.Command{
			{
				Name:  "list",
				Usage: "List all instances with their sync and backup settings",
				Flags: []cli.Flag{},
				Action: func(c context.Context, cmd *cli.Command) error {
					i := incus.NewIncusDriver()
					insts, err := i.GetInstances("")
					if err != nil {
						return err
					}

					for _, inst := range insts {
						s := inst.Sentinel()
						fmt.Printf("%s\n", inst.Name)
						fmt.Printf("  Backup: %t (%s)\n", s.Backup, s.BackupSchedule)
						fmt.Printf("  Sync: %t (%s)\n", s.Sync, s.SyncSchedule)
						if s.Sync {
							fmt.Printf("  Sync Target: %s (pool: %s, suffix: %s)\n", s.SyncTargetRemote, s.SyncTargetPool, s.SyncTargetInstanceSuffix)
						}
					}

					return nil
				},
			},
			{
				Name:  "sync",
				Usage: "Syncs all instances where sync is enabled",
				Flags: []cli.Flag{},
				Action: func(c context.Context, cmd *cli.Command) error {
					i := incus.NewIncusDriver()
					insts, err := i.GetInstances("")
					if err != nil {
						return err
					}

					for _, inst := range insts {
						s := inst.Sentinel()
						if s.Sync {
							fmt.Println(".. syncing", inst.Name)
							err := i.Sync(inst.Name, fmt.Sprintf("%s%s", inst.Name, s.SyncTargetInstanceSuffix), s.SyncTargetRemote, s.SyncTargetPool)
							if err != nil {
								return err
							}
						}
					}

					return nil
				},
			},
			{
				Name:  "backup",
				Usage: "Backs up all instances where backup is enabled",
				Flags: []cli.Flag{},
				Action: func(c context.Context, cmd *cli.Command) error {
					i := incus.NewIncusDriver()
					insts, err := i.GetInstances("")
					if err != nil {
						return err
					}

					for _, inst := range insts {
						s := inst.Sentinel()
						if s.Backup {
							fmt.Println(".. backing up", inst.Name)
							err := i.Backup(inst.Name, []string{})
							if err != nil {
								return err
							}
						}
					}

					return nil
				},
			},
			{
				Name:  "run",
				Usage: "Runs the sentinel that syncs and backs up instances based on their configuration",
				Flags: []cli.Flag{},
				Action: func(c context.Context, cmd *cli.Command) error {
					i := incus.NewIncusDriver()
					n := http_notifier.NewNotifier()

					s := scheduler.NewScheduler(i, n)
					err := s.Run()
					if err != nil {
						return err
					}

					return nil
				},
			},
		},
	}

	if err := cmd.Run(context.Background(), os.Args); err != nil {
		log.Fatal(err)
	}
}
