//go:build integration

package cmd

import (
	"os"
	"path/filepath"
	"strings"
	"testing"

	cpaws "github.com/tidbcloud/controlplane9/internal/aws"
	"github.com/tidbcloud/controlplane9/internal/cluster"
	"github.com/tidbcloud/controlplane9/internal/config"
)

func TestIntegration_UpResumeRestoresCompletedIAMReadyProfile(t *testing.T) {
	configDir := t.TempDir()
	awsConfigPath := filepath.Join(configDir, "config")
	staleConfig := `[profile current-session]
# cp9-session = another-session
# cp9-owner = another-owner
region = us-east-1
output = yaml
credential_process = /bin/bash /old/helper another-source arn:aws:iam::111111111111:role/cp9-developer another-session 3600 another-owner
`
	if err := os.WriteFile(awsConfigPath, []byte(staleConfig), 0o600); err != nil {
		t.Fatal(err)
	}
	t.Setenv("AWS_CONFIG_FILE", awsConfigPath)

	stateDir := t.TempDir()
	lifecycleState := cluster.NewStateForLifecycle("current-session", "current-session", cluster.LifecycleV3)
	lifecycleState.MarkDone(cluster.StepIAMReady)
	if err := cluster.SaveState(stateDir, lifecycleState); err != nil {
		t.Fatal(err)
	}
	if err := cpaws.SaveSessionState(stateDir, &cpaws.SessionState{
		SessionID:     "current-session",
		Owner:         "current-owner@example.com",
		Profile:       "current-session",
		SourceProfile: "current-source",
		Region:        "us-west-2",
		Account:       "222222222222",
		RoleARN:       "arn:aws:iam::222222222222:role/cp9-developer",
		SessionTags: map[string]string{
			cpaws.TagOwner:   "current-owner-example-com",
			cpaws.TagSession: "current-session",
		},
	}); err != nil {
		t.Fatal(err)
	}

	resolved := &config.SessionConfig{
		Name: "current-session",
		Target: config.SessionTargetConfig{
			Cloud:  "aws",
			Region: "us-west-2",
			AWS: config.SessionAWSConfig{
				IAM: config.SessionIAMConfig{
					Profile:       "current-session",
					SourceProfile: "current-source",
					RoleARN:       "arn:aws:iam::222222222222:role/cp9-developer",
				},
			},
		},
	}
	if err := reconcileV1Alpha2CompletedIAMReadyProfile(resolved, stateDir); err == nil ||
		!strings.Contains(err.Error(), "not owned by session") {
		t.Fatalf("reconcile with foreign profile ownership error = %v", err)
	}
	ownedConfig := strings.Replace(staleConfig, "# cp9-session = another-session", "# cp9-session = current-session", 1)
	if err := os.WriteFile(awsConfigPath, []byte(ownedConfig), 0o600); err != nil {
		t.Fatal(err)
	}
	if err := reconcileV1Alpha2CompletedIAMReadyProfile(resolved, stateDir); err != nil {
		t.Fatal(err)
	}

	updated, err := os.ReadFile(awsConfigPath)
	if err != nil {
		t.Fatal(err)
	}
	text := string(updated)
	for _, expected := range []string{
		"# cp9-session = current-session",
		"# cp9-owner = current-owner-example-com",
		"current-source",
		"arn:aws:iam::222222222222:role/cp9-developer",
	} {
		if !strings.Contains(text, expected) {
			t.Errorf("restored AWS config does not contain %q:\n%s", expected, text)
		}
	}
	for _, stale := range []string{"another-session", "arn:aws:iam::111111111111:role/cp9-developer"} {
		if strings.Contains(text, stale) {
			t.Errorf("restored AWS config still contains stale value %q:\n%s", stale, text)
		}
	}
}

func TestIntegration_SessionRejectsCallerSpecifiedRuntimeProfile(t *testing.T) {
	sessionPath := filepath.Join(t.TempDir(), "cp9.yaml")
	sessionConfig := `apiVersion: cp9.tidbcloud.com/v1alpha2
kind: Session
name: cp9-profile-cycle
persona: dev-full
host:
  mode: local-k3d
  ttl: 8h
target:
  cloud: aws
  region: us-west-2
  aws:
    iam:
      profile: cp9
      source_profile: current-source
      role_arn: arn:aws:iam::222222222222:role/cp9-developer
terraform:
  repo: .
  ref: main
  path: terraform/aws/cp9-substrate
  var_file: terraform/aws/cp9-substrate/premium.tfvars
tilt:
  mode: up
  file: ./personas/dev-full/runtime/example.Tiltfile
`
	if err := os.WriteFile(sessionPath, []byte(sessionConfig), 0o600); err != nil {
		t.Fatal(err)
	}

	_, err := config.LoadSession(sessionPath)
	if err == nil {
		t.Fatal("LoadSession succeeded with caller-specified target.aws.iam.profile")
	}
	if !strings.Contains(err.Error(), "target.aws.iam.profile is deprecated") {
		t.Fatalf("LoadSession error = %q, want derived-profile guidance", err)
	}
}
