package control

import (
	"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
	commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
	apeCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
	"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
	"github.com/spf13/cobra"
)

var addRuleCmd = &cobra.Command{
	Use:   "add-rule",
	Short: "Add local override",
	Long:  "Add local APE rule to a node with following format:\n<action>[:action_detail] <operation> [<condition1> ...] <resource>",
	Example: `control add-rule --endpoint ... -w ... --address ... --chain-id ChainID --cid ... --rule "allow Object.Get *"
--rule "deny Object.Get EbxzAdz5LB4uqxuz6crWKAumBNtZyK2rKsqQP7TdZvwr/*"
--rule "deny:QuotaLimitReached Object.Put ResourceCondition:Department=HR *"

control add-rule --endpoint ... -w ... --address ... --chain-id ChainID --cid ... --path some_chain.json
`,
	Run: addRule,
}

func addRule(cmd *cobra.Command, _ []string) {
	pk := key.Get(cmd)

	target := parseTarget(cmd)

	parsed := apeCmd.ParseChain(cmd)

	req := &control.AddChainLocalOverrideRequest{
		Body: &control.AddChainLocalOverrideRequest_Body{
			Target: target,
			Chain:  parsed.Bytes(),
		},
	}

	signRequest(cmd, pk, req)

	cli := getClient(cmd, pk)

	var resp *control.AddChainLocalOverrideResponse
	var err error
	err = cli.ExecRaw(func(client *client.Client) error {
		resp, err = control.AddChainLocalOverride(client, req)
		return err
	})
	commonCmd.ExitOnErr(cmd, "rpc error: %w", err)

	verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
	cmd.Println("\nRule has been added.")
}

func initControlAddRuleCmd() {
	initControlFlags(addRuleCmd)

	ff := addRuleCmd.Flags()
	ff.StringArray(apeCmd.RuleFlag, []string{}, "Rule statement")
	ff.String(apeCmd.PathFlag, "", "Path to encoded chain in JSON or binary format")
	ff.String(apeCmd.ChainIDFlag, "", "Assign ID to the parsed chain")
	ff.String(apeCmd.TargetNameFlag, "", apeCmd.TargetNameFlagDesc)
	ff.String(apeCmd.TargetTypeFlag, "", apeCmd.TargetTypeFlagDesc)
	_ = addRuleCmd.MarkFlagRequired(apeCmd.TargetTypeFlag)
	ff.Bool(apeCmd.ChainIDHexFlag, false, "Flag to parse chain ID as hex")

	addRuleCmd.MarkFlagsMutuallyExclusive(apeCmd.PathFlag, apeCmd.RuleFlag)
}