package presets

import (
	"crypto/sha256"
	"fmt"
	"io/fs"
	"slices"
	"strings"
	"testing"
)

func TestOfficialSkillLibrariesIncludeWorkflowPlanAuthor(t *testing.T) {
	libraries, err := OfficialSkillLibraries("zh-Hans-CN")
	if err != nil {
		t.Fatalf("OfficialSkillLibraries: %v", err)
	}
	if len(libraries) != 3 {
		t.Fatalf("len(OfficialSkillLibraries) = %d, want 3", len(libraries))
	}
	var workflow SkillLibraryInfo
	for _, library := range libraries {
		if library.Slug == "agentteam-workflow-plan-author-skills" {
			workflow = library
			break
		}
	}
	if workflow.Slug == "" {
		t.Fatal("workflow plan author library is missing")
	}
	if workflow.ArchiveName != "agentteam-workflow-plan-author-skills.zip" {
		t.Fatalf("workflow ArchiveName = %q", workflow.ArchiveName)
	}
	if workflow.SystemSubject != "agentteam-system" {
		t.Fatalf("workflow SystemSubject = %q", workflow.SystemSubject)
	}
	if workflow.Visibility != "public" {
		t.Fatalf("workflow Visibility = %q", workflow.Visibility)
	}
	if workflow.Name != "AgentTeam 工作流计划生成" {
		t.Fatalf("workflow Name = %q", workflow.Name)
	}
	if workflow.Description != "根据自然语言流程需求创建和更新已验证的 AgentTeam 工作流计划。" {
		t.Fatalf("workflow Description = %q", workflow.Description)
	}
	if workflow.TemplateLocale != LocaleSimplifiedChinese {
		t.Fatalf("workflow TemplateLocale = %q, want %q", workflow.TemplateLocale, LocaleSimplifiedChinese)
	}
	if len(workflow.SkillSlugs) != 1 || workflow.SkillSlugs[0] != "workflow-plan-author" {
		t.Fatalf("workflow SkillSlugs = %#v", workflow.SkillSlugs)
	}
}

func TestOfficialSkillLibrariesIncludePinnedExternalLibrariesWithoutAutoRuntimeAccess(t *testing.T) {
	libraries, err := OfficialSkillLibraries(LocaleSimplifiedChinese)
	if err != nil {
		t.Fatalf("OfficialSkillLibraries: %v", err)
	}
	bySlug := map[string]SkillLibraryInfo{}
	for _, library := range libraries {
		bySlug[library.Slug] = library
		if library.SourceFingerprint == "" {
			t.Errorf("library %q missing SourceFingerprint", library.Slug)
		}
	}

	superpowers := bySlug["superpowers"]
	if superpowers.Slug == "" {
		t.Fatal("missing superpowers")
	}
	if superpowers.AutoAgentAccess {
		t.Fatal("superpowers must not automatically enter every Agent runtime")
	}
	if superpowers.SourceRepo != "https://github.com/obra/superpowers" {
		t.Fatalf("Superpowers SourceRepo = %q", superpowers.SourceRepo)
	}
	if superpowers.SourceCommit != "44c9b2d6e889982ac18c27d05a19fefe335194e1" {
		t.Fatalf("Superpowers SourceCommit = %q", superpowers.SourceCommit)
	}
	for _, slug := range []string{"brainstorming", "test-driven-development", "systematic-debugging", "verification-before-completion"} {
		if !slices.Contains(superpowers.SkillSlugs, slug) {
			t.Errorf("Superpowers skill slugs missing %q", slug)
		}
	}

	addy := bySlug["addy-agent-skills"]
	if addy.Slug == "" {
		t.Fatal("missing addy-agent-skills")
	}
	if addy.AutoAgentAccess {
		t.Fatal("addy-agent-skills must not automatically enter every Agent runtime")
	}
	if addy.SourceRepo != "https://github.com/addyosmani/agent-skills" {
		t.Fatalf("Agent Skills SourceRepo = %q", addy.SourceRepo)
	}
	if addy.SourceCommit != "7829ffd90d973b6325f5f12f1b1226dcace74443" {
		t.Fatalf("Agent Skills SourceCommit = %q", addy.SourceCommit)
	}
	for _, slug := range []string{"frontend-ui-engineering", "browser-testing-with-devtools"} {
		if !slices.Contains(addy.SkillSlugs, slug) {
			t.Errorf("Agent Skills skill slugs missing %q", slug)
		}
	}
}

func TestOfficialSkillContentFallsBackToEnglishAndUsesLibrarySlugName(t *testing.T) {
	content, err := OfficialSkillContent("superpowers", "brainstorming", LocaleSimplifiedChinese)
	if err != nil {
		t.Fatalf("OfficialSkillContent: %v", err)
	}
	if content.SkillSlug != "brainstorming" {
		t.Fatalf("SkillSlug = %q", content.SkillSlug)
	}
	if !strings.Contains(content.Description, "creative work") {
		t.Fatalf("Description = %q", content.Description)
	}
	if !strings.Contains(content.Content, "name: brainstorming") {
		t.Fatal("content should preserve upstream SKILL.md frontmatter")
	}
}

func TestSkillFrontmatterDescriptionAcceptsCRLF(t *testing.T) {
	description, err := skillFrontmatterDescription("---\r\nname: test\r\ndescription: Windows checkout\r\n---\r\n# Test\r\n")
	if err != nil {
		t.Fatalf("skillFrontmatterDescription: %v", err)
	}
	if description != "Windows checkout" {
		t.Fatalf("Description = %q, want %q", description, "Windows checkout")
	}
}

func TestOfficialWorkflowPlanAuthorLibraryPreservesValidatedContent(t *testing.T) {
	expectedSkillHashes := map[string]string{
		LocaleEnglish:           "b60cc9d0373c20e8b9bdee48fea482ae7e3c5bdeb53d377f4e0addd1499e64a1",
		LocaleSimplifiedChinese: "6dd71af082b57bf8f2d488cf72d009030a928d5ca73cf733a8d6352077b13cfc",
		LocaleJapanese:          "555dfe9d4d9ccce2551b3a97eac054a2dc229ef989fdbee85b97eb26f22234fb",
	}
	for _, locale := range []string{
		LocaleEnglish,
		LocaleSimplifiedChinese,
		LocaleJapanese,
	} {
		t.Run(locale, func(t *testing.T) {
			skillFS, err := OfficialSkillLibraryFS("agentteam-workflow-plan-author-skills", locale)
			if err != nil {
				t.Fatalf("OfficialSkillLibraryFS(%q): %v", locale, err)
			}
			var paths []string
			if err := fs.WalkDir(skillFS, "skills", func(path string, entry fs.DirEntry, err error) error {
				if err != nil {
					return err
				}
				if !entry.IsDir() {
					paths = append(paths, path)
				}
				return nil
			}); err != nil {
				t.Fatalf("walk workflow-plan-author files for %q: %v", locale, err)
			}
			slices.Sort(paths)
			wantPaths := []string{
				"skills/workflow-plan-author/SKILL.md",
				"skills/workflow-plan-author/references/complete-plan.yaml",
			}
			if !slices.Equal(paths, wantPaths) {
				t.Fatalf("workflow-plan-author files for %q = %#v, want %#v", locale, paths, wantPaths)
			}
			expectedHashes := map[string]string{
				"SKILL.md":                      expectedSkillHashes[locale],
				"references/complete-plan.yaml": "5a72c847e0bed3aeeb0e0a7ccf4d687e654bfc343b23dc80e3c3ff1aff1e3115",
			}
			for name, expectedHash := range expectedHashes {
				content, err := fs.ReadFile(skillFS, "skills/workflow-plan-author/"+name)
				if err != nil {
					t.Fatalf("read workflow-plan-author %q for %q: %v", name, locale, err)
				}
				if actualHash := fmt.Sprintf("%x", sha256.Sum256(content)); actualHash != expectedHash {
					t.Fatalf("%s hash for %q = %q, want %q", name, locale, actualHash, expectedHash)
				}
			}
		})
	}
}
