package file_storage

import (
	"strings"
	"testing"
)

func TestFileType(t *testing.T) {
	cases := []struct {
		filename string
		want     string
	}{
		{"clue.pdf", "pdf"},
		{"clue.PDF", "pdf"},
		{"photo.jpg", "image"},
		{"photo.jpeg", "image"},
		{"photo.PNG", "image"},
		{"photo.gif", "image"},
		{"photo.webp", "image"},
		{"audio.mp3", "audio"},
		{"audio.ogg", "audio"},
		{"audio.wav", "audio"},
		{"audio.m4a", ""},
		{"photo.PNG?v=2", "image"},
		{"http://domain/api/files/photo.pdf", "pdf"},
		{"noextension", ""},
		{"", ""},
	}
	for _, c := range cases {
		if got := FileType(c.filename); got != c.want {
			t.Errorf("FileType(%q) = %q, want %q", c.filename, got, c.want)
		}
	}
}

func TestNewName(t *testing.T) {
	a, err := NewName()
	if err != nil {
		t.Fatalf("NewName: %v", err)
	}
	b, err := NewName()
	if err != nil {
		t.Fatalf("NewName: %v", err)
	}
	if a == "" || b == "" {
		t.Fatalf("NewName вернул пустое имя")
	}
	if a == b {
		t.Errorf("NewName вернул одинаковые имена %q и %q", a, b)
	}
	// hex-токен 16 байт = 32 символа
	if len(a) != 32 {
		t.Errorf("длина имени = %d, want 32", len(a))
	}
}

func TestMimeFor(t *testing.T) {
	png := []byte("\x89PNG\r\n\x1a\n" + strings.Repeat("x", 16))

	t.Run("explicit Mime wins", func(t *testing.T) {
		f := &File{Name: "clue.pdf", Data: png, Mime: "application/pdf"}
		if got := mimeFor(f); got != "application/pdf" {
			t.Errorf("mimeFor = %q, want application/pdf", got)
		}
	})

	t.Run("empty Mime falls back to content sniff", func(t *testing.T) {
		f := &File{Name: "clue.bin", Data: png}
		if got := mimeFor(f); got != "image/png" {
			t.Errorf("mimeFor = %q, want image/png", got)
		}
	})

	t.Run("empty Mime and unknown content falls back to extension", func(t *testing.T) {
		f := &File{Name: "clue.pdf", Data: []byte("not really a pdf")}
		if got := mimeFor(f); got != "application/pdf" {
			t.Errorf("mimeFor = %q, want application/pdf по расширению", got)
		}
	})
}

func TestMimeFromData(t *testing.T) {
	cases := []struct {
		name     string
		data     []byte
		filename string
		want     string
	}{
		{"pdf", []byte("%PDF-1.7 fake"), "clue.pdf", "application/pdf"},
		{"png", []byte("\x89PNG\r\n\x1a\nxxx"), "photo.png", "image/png"},
		{"html falls back to extension", []byte("<html>hi</html>"), "photo.png", "image/png"},
		{"html unknown extension", []byte("<html>hi</html>"), "clue.xyz", "application/octet-stream"},
		{"unknown falls back to extension", []byte{0x00, 0x01, 0x02, 0x03}, "clue.pdf", "application/pdf"},
		{"empty data falls back", nil, "clue.pdf", "application/pdf"},
	}
	for _, c := range cases {
		if got := mimeFromData(c.data, c.filename); got != c.want {
			t.Errorf("mimeFromData(%q, %q) = %q, want %q", c.name, c.filename, got, c.want)
		}
	}
}
