package files

import (
	"strings"
	"testing"
	"time"
)

func TestSignVerifyRoundTrip(t *testing.T) {
	secret := []byte("0123456789abcdef0123456789abcdef")
	now := time.Now()
	token := SignToken(secret, "01JFILE", now.Add(time.Hour))

	if !VerifyToken(secret, "01JFILE", token, now) {
		t.Fatal("fresh token must verify")
	}
	if !VerifyToken(secret, "01JFILE", token, now.Add(59*time.Minute)) {
		t.Fatal("token must verify just before expiry")
	}
}

func TestVerifyRejections(t *testing.T) {
	secret := []byte("0123456789abcdef0123456789abcdef")
	now := time.Now()
	token := SignToken(secret, "01JFILE", now.Add(time.Hour))

	tests := []struct {
		name   string
		fileID string
		token  string
		at     time.Time
	}{
		{"expired", "01JFILE", token, now.Add(2 * time.Hour)},
		{"wrong file", "01JOTHER", token, now},
		{"garbage token", "01JFILE", "not-a-token", now},
		{"empty token", "01JFILE", "", now},
		{"truncated token", "01JFILE", token[:len(token)-10], now},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if VerifyToken(secret, tt.fileID, tt.token, tt.at) {
				t.Error("must not verify")
			}
		})
	}

	if VerifyToken([]byte("another-secret-another-secret-xx"), "01JFILE", token, now) {
		t.Error("different secret must not verify")
	}
}

func TestSignedURLShape(t *testing.T) {
	secret := []byte("0123456789abcdef0123456789abcdef")
	u := SignedURL("http://localhost:8787", secret, "01JFILE", time.Now().Add(time.Hour))
	if !strings.HasPrefix(u, "http://localhost:8787/files/01JFILE?st=") {
		t.Fatalf("unexpected URL %q", u)
	}
	token := u[strings.Index(u, "?st=")+4:]
	if !VerifyToken(secret, "01JFILE", token, time.Now()) {
		t.Fatal("token embedded in URL must verify")
	}
}
