package writecache

import (
	"context"
	"fmt"

	common "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal"
	schema "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/schema/writecache"
	"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/tui"
	"github.com/rivo/tview"
	"github.com/spf13/cobra"
	"go.etcd.io/bbolt"
)

var tuiCMD = &cobra.Command{
	Use:   "explore",
	Short: "Write cache exploration with a terminal UI",
	Long: `Launch a terminal UI to explore write cache and search for data.

Available search filters:
- cid  CID
- oid  OID
- addr CID/OID
`,
	Run: tuiFunc,
}

var initialPrompt string

func init() {
	common.AddComponentPathFlag(tuiCMD, &vPath)

	tuiCMD.Flags().StringVar(
		&initialPrompt,
		"filter",
		"",
		"Filter prompt to start with, format 'tag:value [+ tag:value]...'",
	)
}

func tuiFunc(cmd *cobra.Command, _ []string) {
	common.ExitOnErr(cmd, runTUI(cmd))
}

func runTUI(cmd *cobra.Command) error {
	db, err := openDB(false)
	if err != nil {
		return fmt.Errorf("couldn't open database: %w", err)
	}
	defer db.Close()

	ctx, cancel := context.WithCancel(cmd.Context())
	defer cancel()

	app := tview.NewApplication()
	ui := tui.NewUI(ctx, app, db, schema.WritecacheParser, nil)

	_ = ui.AddFilter("cid", tui.CIDParser, "CID")
	_ = ui.AddFilter("oid", tui.OIDParser, "OID")
	_ = ui.AddCompositeFilter("addr", tui.AddressParser, "CID/OID")

	err = ui.WithPrompt(initialPrompt)
	if err != nil {
		return fmt.Errorf("invalid filter prompt: %w", err)
	}

	app.SetRoot(ui, true).SetFocus(ui)
	return app.Run()
}

func openDB(writable bool) (*bbolt.DB, error) {
	db, err := bbolt.Open(vPath, 0o600, &bbolt.Options{
		ReadOnly: !writable,
	})
	if err != nil {
		return nil, err
	}
	return db, nil
}