package tcaction

import (
	"context"
	"strings"
	"testing"

	opent "github.com/tidbcloud/devops/entity/operation"
	apiv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/cluster-server/v1"
	"google.golang.org/protobuf/encoding/protojson"
)

func TestGetParamRecoverAZBuildsFullRequest(t *testing.T) {
	a := &createOperation{
		meta:    ActionRecoverAZ,
		fixedOp: OperationTypeRecoverAZ,
		opIDOut: opent.OutputOperationIDRecoverAZ,
	}
	ins := &opent.Instance{
		ID: 42,
		Params: map[opent.ParamName]string{
			opent.ParamClusterID:        "12345",
			opent.ParamAvailabilityZone: "us-east-1a",
			opent.ParamForce:            "true",
		},
	}
	param, err := a.getParam(context.Background(), ins)
	if err != nil {
		t.Fatalf("getParam: %v", err)
	}
	if param.req.GetOperation().GetType() != apiv1.Operation_RECOVER_AZ {
		t.Fatalf("type=%v", param.req.GetOperation().GetType())
	}
	if param.req.GetOperation().GetRecoverAz().GetAvailabilityZone() != "us-east-1a" {
		t.Fatalf("az=%v", param.req.GetOperation().GetRecoverAz())
	}
	b, err := protojson.Marshal(param.req)
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("body=%s", string(b))
	for _, part := range []string{`"type":"RECOVER_AZ"`, `"recoverAz"`, `"us-east-1a"`} {
		if !strings.Contains(string(b), part) {
			t.Fatalf("body missing %s: %s", part, b)
		}
	}
}

func TestGetParamRecoverAZRequiresAZ(t *testing.T) {
	a := &createOperation{
		meta:    ActionRecoverAZ,
		fixedOp: OperationTypeRecoverAZ,
		opIDOut: opent.OutputOperationIDRecoverAZ,
	}
	ins := &opent.Instance{
		ID: 42,
		Params: map[opent.ParamName]string{
			opent.ParamClusterID: "12345",
			opent.ParamForce:     "true",
		},
	}
	_, err := a.getParam(context.Background(), ins)
	if err == nil {
		t.Fatal("expected error")
	}
}

func TestGetParamRejectsUnknownOperationType(t *testing.T) {
	a := &createOperation{
		meta:    ActionCreateOperation,
		opIDOut: opent.OutputOperationID,
	}
	ins := &opent.Instance{
		ID: 1,
		Params: map[opent.ParamName]string{
			opent.ParamClusterID:     "12345",
			opent.ParamOperationType: "NotARealType",
		},
	}
	_, err := a.getParam(context.Background(), ins)
	if err == nil || !strings.Contains(err.Error(), "unsupported or incomplete") {
		t.Fatalf("expected unsupported error, got %v", err)
	}
}
