package initialize

import (
	"fmt"

	"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
	"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
	"github.com/nspcc-dev/neo-go/pkg/io"
	"github.com/nspcc-dev/neo-go/pkg/rpcclient/rolemgmt"
	"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
	"github.com/nspcc-dev/neo-go/pkg/vm/emit"
)

func setNotaryAndAlphabetNodes(c *helper.InitializeContext) error {
	if ok, err := setRolesFinished(c); ok || err != nil {
		if err == nil {
			c.Command.Println("Stage 2: already performed.")
		}
		return err
	}

	var pubs []any
	for _, acc := range c.Accounts {
		pubs = append(pubs, acc.PrivateKey().PublicKey().Bytes())
	}

	w := io.NewBufBinWriter()
	emit.AppCall(w.BinWriter, rolemgmt.Hash, "designateAsRole",
		callflag.States|callflag.AllowNotify, int64(noderoles.P2PNotary), pubs)
	emit.AppCall(w.BinWriter, rolemgmt.Hash, "designateAsRole",
		callflag.States|callflag.AllowNotify, int64(noderoles.NeoFSAlphabet), pubs)

	if err := c.SendCommitteeTx(w.Bytes(), false); err != nil {
		return fmt.Errorf("send committee transaction: %w", err)
	}

	err := c.AwaitTx()
	if err != nil {
		err = fmt.Errorf("await committee transaction: %w", err)
	}
	return err
}

func setRolesFinished(c *helper.InitializeContext) (bool, error) {
	height, err := c.Client.GetBlockCount()
	if err != nil {
		return false, err
	}

	pubs, err := helper.GetDesignatedByRole(c.ReadOnlyInvoker, rolemgmt.Hash, noderoles.NeoFSAlphabet, height)
	return len(pubs) == len(c.Wallets), err
}