package main

import (
	"baron-sso-backend/internal/domain"
	"baron-sso-backend/internal/service"
	"context"
	"flag"
	"fmt"
	"log"
)

func main() {
	dryRun := flag.Bool("dry-run", true, "변경 대상만 출력하고 Kratos identity를 수정하지 않습니다")
	maintenanceWindow := flag.Bool("maintenance-window", false, "승인된 정비 시간에만 실제 변경을 허용합니다")
	markMirrorStale := flag.Bool("mark-mirror-stale", false, "실행 전 Redis identity mirror를 stale로 표시했음을 확인합니다")
	flag.Parse()

	if !*dryRun && (!*maintenanceWindow || !*markMirrorStale) {
		log.Fatal("refusing to update Kratos identities: pass --dry-run=false --maintenance-window --mark-mirror-stale after marking identity mirror stale")
	}

	kratosAdmin := service.NewKratosAdminService()
	ctx := context.Background()

	identities, err := kratosAdmin.ListIdentities(ctx)
	if err != nil {
		log.Fatalf("Failed to list identities: %v", err)
	}

	count := 0
	for _, id := range identities {
		traits := id.Traits
		changed := false

		if r, ok := traits["role"].(string); ok {
			norm := domain.NormalizeRole(r)
			if norm != r && norm == domain.RoleUser {
				traits["role"] = norm
				changed = true
			}
		} else if g, ok := traits["grade"].(string); ok {
			if norm, ok := domain.NormalizeRoleAlias(g); ok {
				traits["role"] = norm
				delete(traits, "grade")
				changed = true
			}
		}

		if changed {
			if *dryRun {
				count++
				fmt.Printf("Would update %s\n", id.ID)
				continue
			}
			_, err := kratosAdmin.UpdateIdentity(ctx, id.ID, traits, id.State)
			if err != nil {
				log.Printf("Failed to update %s: %v", id.ID, err)
			} else {
				count++
				fmt.Printf("Updated %s\n", id.ID)
			}
		}
	}
	if *dryRun {
		fmt.Printf("Total candidates: %d\n", count)
	} else {
		fmt.Printf("Total updated: %d\n", count)
		fmt.Println("Identity mirror was marked stale before maintenance; run full mirror refresh and drift report before trusting cached user lists.")
	}
}
