package api

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/ponzischeme89/memby/server/internal/store"
)

// The television decodes this into GatewayTrickplay; the matching Kotlin test is
// `decodes a seek preview layout` in GatewayPayloadTest. Rename a field on either side and
// one of them fails before a TV ever sees it.
func TestTrickplayManifestShape(t *testing.T) {
	raw, err := json.Marshal(trickplayManifest{
		Available: true, IntervalMs: 10_000, Count: 817, Width: 320, Height: 172,
	})
	if err != nil {
		t.Fatalf("marshal: %v", err)
	}
	want := `{"available":true,"intervalMs":10000,"count":817,"width":320,"height":172}`
	if string(raw) != want {
		t.Fatalf("manifest = %s, want %s", raw, want)
	}
}

func TestTrickplayManifestOmitsTheRestWhenUnavailable(t *testing.T) {
	// A title with no thumbnails, an operator who has turned the feature off and a gateway
	// with no Emby all mean the same thing to a television, so they must all look the same
	// on the wire — and none of them may carry a count it would try to draw from.
	raw, err := json.Marshal(trickplayManifest{})
	if err != nil {
		t.Fatalf("marshal: %v", err)
	}
	if string(raw) != `{"available":false}` {
		t.Fatalf("manifest = %s", raw)
	}
}

func TestTrickplayAnswersUnavailableRatherThanFailing(t *testing.T) {
	// A gateway with no Emby configured still answers, with 200 and "no previews". The
	// seek indicator is a complete answer without a thumbnail, and an error here would be
	// one nobody could act on, logged once per press of Right.
	s := &Server{}
	req := httptest.NewRequest(http.MethodGet, "/v1/items/42/trickplay", nil)
	req.SetPathValue("id", "42")
	rec := httptest.NewRecorder()

	s.handleTrickplay(rec, req, store.Session{EmbyUserID: "user-1"})

	if rec.Code != http.StatusOK {
		t.Fatalf("status = %d, want 200", rec.Code)
	}
	var manifest trickplayManifest
	if err := json.Unmarshal(rec.Body.Bytes(), &manifest); err != nil {
		t.Fatalf("unmarshal: %v", err)
	}
	if manifest.Available {
		t.Fatal("a gateway with no Emby offered seek previews")
	}
}

func TestTrickplayFrameRejectsAnUnreadableIndex(t *testing.T) {
	s := &Server{}
	for _, frame := range []string{"", "-1", "twelve", "12.png.jpg"} {
		req := httptest.NewRequest(http.MethodGet, "/v1/items/42/trickplay/"+frame, nil)
		req.SetPathValue("id", "42")
		req.SetPathValue("frame", frame)
		rec := httptest.NewRecorder()

		s.handleTrickplayFrame(rec, req, store.Session{EmbyUserID: "user-1"})

		if rec.Code != http.StatusNotFound {
			t.Fatalf("frame %q: status = %d, want 404", frame, rec.Code)
		}
	}
}
