package feedback

import (
	"archive/zip"
	"bytes"
	"testing"

	"ymhut-box/server/feedback-mailer/internal/config"
)

func TestSubmissionSignatureIsStable(t *testing.T) {
	signature := SignWithKey(
		"ymhut-box-feedback-client-v1",
		"1760000000",
		"abc123",
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		`{"ok":true}`,
	)

	const expected = "9bb27ac870cddf4b9eb02961f2f744bb4cf02b7a08e190ede5d836e5c946ad2e"
	if signature != expected {
		t.Fatalf("signature mismatch: got %s want %s", signature, expected)
	}
}

func TestDecryptPackageAndReadFeedbackPackage(t *testing.T) {
	var zipBuffer bytes.Buffer
	writer := zip.NewWriter(&zipBuffer)
	feedbackEntry, err := writer.Create("feedback.json")
	if err != nil {
		t.Fatal(err)
	}
	if _, err := feedbackEntry.Write([]byte(`{"request":{"title":"Crash","type":"issue","severity":"major","contact":"dev@example.com","body":"Steps"}}`)); err != nil {
		t.Fatal(err)
	}
	summaryEntry, err := writer.Create("summary.txt")
	if err != nil {
		t.Fatal(err)
	}
	if _, err := summaryEntry.Write([]byte("summary text")); err != nil {
		t.Fatal(err)
	}
	if err := writer.Close(); err != nil {
		t.Fatal(err)
	}

	encrypted, err := DebugEncryptPackageForTest(zipBuffer.Bytes(), "ymhut-box-feedback-package-v1", []byte("123456789012"))
	if err != nil {
		t.Fatal(err)
	}
	plain, err := DecryptPackage(encrypted, "ymhut-box-feedback-package-v1")
	if err != nil {
		t.Fatal(err)
	}
	if !bytes.Equal(plain, zipBuffer.Bytes()) {
		t.Fatal("decrypted package did not match original zip")
	}

	info, err := ReadFeedbackPackage(plain)
	if err != nil {
		t.Fatal(err)
	}
	if info.Request["title"] != "Crash" || info.Summary != "summary text" {
		t.Fatalf("unexpected package info: %+v", info)
	}
	if len(info.Files) != 2 {
		t.Fatalf("expected two files, got %v", info.Files)
	}
}

func TestNormalizeCode(t *testing.T) {
	if got := NormalizeCode(" fb-20260604-abc123 "); got != "FB-20260604-ABC123" {
		t.Fatalf("unexpected normalized code %q", got)
	}
	if got := NormalizeCode("FB-20260604-XYZ123"); got != "" {
		t.Fatalf("invalid code was accepted: %q", got)
	}
}

func TestReadFeedbackPackageRejectsUnsafeZipPath(t *testing.T) {
	var zipBuffer bytes.Buffer
	writer := zip.NewWriter(&zipBuffer)
	entry, err := writer.Create("../evil.txt")
	if err != nil {
		t.Fatal(err)
	}
	if _, err := entry.Write([]byte("evil")); err != nil {
		t.Fatal(err)
	}
	if err := writer.Close(); err != nil {
		t.Fatal(err)
	}

	if _, err := ReadFeedbackPackageWithGuard(zipBuffer.Bytes(), config.Default(".").UploadGuard); err == nil {
		t.Fatal("expected unsafe zip path to be rejected")
	}
}
