package lookup

import (
	"context"
	"testing"
	"time"
)

// A TTL of zero means no cache: nothing is read from it, and nothing is written
// to it either.
//
// It is a real thing to want. An operator correcting their own QRZ record — or
// chasing a DXpedition whose page changes during the operation — otherwise
// waits out thirty days before OpsLog will ask again. Clearing the cache by
// hand works once; switching it off is the setting for a session where the
// answers are moving.
func TestATTLOfZeroSwitchesTheCacheOff(t *testing.T) {
	c := testCache(t)
	ctx := context.Background()

	if err := c.Put(ctx, Result{Callsign: "M0ABC", Name: "Ann", Source: "qrz"}); err != nil {
		t.Fatalf("put: %v", err)
	}
	if _, ok := c.Get(ctx, "M0ABC"); !ok {
		t.Fatal("the cache did not hold a fresh entry while switched on")
	}

	c.SetTTL(0)
	if c.Enabled() {
		t.Error("Enabled() is true with a zero TTL")
	}
	if _, ok := c.Get(ctx, "M0ABC"); ok {
		t.Error("a cached entry was still returned with the cache off — the provider would never be asked again")
	}
	// And nothing new is stored: those rows would only sit there going stale,
	// waiting for the day the cache is switched back on.
	if err := c.Put(ctx, Result{Callsign: "M0XYZ", Name: "Bob", Source: "qrz"}); err != nil {
		t.Fatalf("put with the cache off: %v", err)
	}
	c.SetTTL(30 * 24 * time.Hour)
	if _, ok := c.Get(ctx, "M0XYZ"); ok {
		t.Error("a lookup made while the cache was off was written to it anyway")
	}
	// The entry from before it was switched off is still there — switching off
	// is not the same as clearing, and the Clear cache button remains the way to
	// throw the contents away.
	if _, ok := c.Get(ctx, "M0ABC"); !ok {
		t.Error("switching the cache off discarded what it already held")
	}
}

// A negative lifetime is meaningless, and rounding it into either "off" or a
// default would be a guess. It is ignored instead.
func TestANegativeTTLIsIgnored(t *testing.T) {
	c := testCache(t)
	c.SetTTL(7 * 24 * time.Hour)
	c.SetTTL(-1)
	if !c.Enabled() {
		t.Fatal("a negative TTL switched the cache off")
	}
	if c.ttl != 7*24*time.Hour {
		t.Errorf("ttl = %v after a negative value, want the 7 days it already had", c.ttl)
	}
}

// The constructor's zero is the DEFAULT, not "off": at startup the settings
// have not been read, and beginning with no cache would hammer the provider for
// the first seconds of every launch.
func TestNewCacheWithZeroStillCaches(t *testing.T) {
	c := testCache(t) // built with NewCache(conn, 0)
	if !c.Enabled() {
		t.Error("a cache built with a zero TTL started switched off")
	}
}
