package release

import (
	"crypto/ed25519"
	"crypto/rand"
	"encoding/base64"
	"testing"
	"time"
)

func TestSignVerifyRoundTrip(t *testing.T) {
	pub, priv, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}
	m := &Manifest{
		Version:    "1.2.3",
		Channel:    "stable",
		ReleasedAt: time.Now().UTC().Truncate(time.Second),
		Artifacts: []Artifact{
			{Name: "bj-server", File: "bj-server", SHA256: "abc", Size: 100, Exec: true},
		},
	}
	sm, err := Sign(m, priv, "main")
	if err != nil {
		t.Fatalf("Sign: %v", err)
	}
	got, err := Verify(sm, pub)
	if err != nil {
		t.Fatalf("Verify: %v", err)
	}
	if got.Version != m.Version || got.Channel != m.Channel || len(got.Artifacts) != 1 {
		t.Fatalf("manifest mismatch: %+v", got)
	}
	if got.Schema != CurrentSchema {
		t.Fatalf("schema = %d, want %d", got.Schema, CurrentSchema)
	}
}

func TestVerifyRejectsTamper(t *testing.T) {
	pub, priv, _ := ed25519.GenerateKey(rand.Reader)
	m := &Manifest{Version: "1.0.0", Channel: "stable", Artifacts: []Artifact{{Name: "x"}}}
	sm, _ := Sign(m, priv, "main")
	// Подменяем payload на другой манифест — подпись не должна сойтись.
	other := &Manifest{Version: "9.9.9", Channel: "stable", Artifacts: []Artifact{{Name: "evil"}}}
	bad, _ := other.Canonical()
	sm.Payload = base64.StdEncoding.EncodeToString(bad)
	if _, err := Verify(sm, pub); err == nil {
		t.Fatal("Verify принял подделанный payload")
	}
}

func TestVerifyRejectsWrongKey(t *testing.T) {
	_, priv, _ := ed25519.GenerateKey(rand.Reader)
	other, _, _ := ed25519.GenerateKey(rand.Reader) // чужой публичный ключ
	m := &Manifest{Version: "1.0.0", Channel: "stable", Artifacts: []Artifact{{Name: "x"}}}
	sm, _ := Sign(m, priv, "main")
	if _, err := Verify(sm, other); err == nil {
		t.Fatal("Verify принял подпись чужим ключом")
	}
}
