package core

import (
	"encoding/json"
	"testing"
	"time"
)

func TestItemFormatsExist(t *testing.T) {
	for name := range AvailableFormats {
		formatter, err := FormatAs(name)
		if err != nil {
			t.Fatalf("error getting formatter for available format %s: %v", name, err)
		}
		if formatter == nil {
			t.Fatalf("formatter %s is nil", name)
		}
	}
}

func TestItemRoundTrip(t *testing.T) {
	db := EphemeralDb(t)
	if err := AddSource(db, "_"); err != nil {
		t.Fatalf("failed to create source: %v", err)
	}

	item1 := Item{
		Source:  "_",
		Id:      "a",
		Created: 0,
		Active:  true,
		Title:   "title",
		Author:  "author",
		Body:    "body",
		Link:    "link",
		Time:    123456,
		Action: map[string]json.RawMessage{
			"hello": json.RawMessage(`"world"`),
		},
	}
	if err := AddItems(db, []Item{item1}); err != nil {
		t.Fatalf("update failed: %v", err)
	}
	item2, err := GetItem(db, item1.Source, item1.Id)
	if err != nil {
		t.Fatalf("could not get item: %v", err)
	}
	item2.Created = 0 // automatically set by db
	if !ItemsAreEqual(item1, item2) {
		t.Fatalf("items are not equal, err %v", err)
	}
}

func TestItemLifecycleTimes(t *testing.T) {
	db := EphemeralDb(t)
	if err := AddSource(db, "_"); err != nil {
		t.Fatal(err)
	}

	now := time.Now()

	// active item with expired ttd is deleted
	add, del, err := UpdateWithFetchedItems(db, "_", nil, []Item{{Source: "_", Id: "_", Ttd: 1}}, now)
	if add != 1 || del != 0 || err != nil {
		t.Fatalf("unexpected update result: %d %d %v", add, del, err)
	}
	add, del, err = UpdateWithFetchedItems(db, "_", nil, []Item{}, now.Add(time.Second*5))
	if add != 0 || del != 1 || err != nil {
		t.Fatalf("unexpected update result: %d %d %v", add, del, err)
	}

	// inactive item with live ttl is kept
	add, del, err = UpdateWithFetchedItems(db, "_", nil, []Item{{Source: "_", Id: "_", Ttl: 60}}, now)
	if add != 1 || del != 0 || err != nil {
		t.Fatalf("unexpected update result: %d %d %v", add, del, err)
	}
	if _, err = DeactivateItem(db, "_", "_"); err != nil {
		t.Fatal(err)
	}
	add, del, err = UpdateWithFetchedItems(db, "_", nil, []Item{}, now.Add(time.Second*5))
	if add != 0 || del != 0 || err != nil {
		t.Fatalf("unexpected update result: %d %d %v", add, del, err)
	}
}