package internal

import (
	"sync"
	"time"

	"github.com/miekg/dns"
)

type Cache interface {
	Purge(name string)
	PurgeAll()
	LookupRecord(name string) []dns.RR
	SaveAnswers(name string, answers []dns.RR)
}

type Memory struct {
	sync.Mutex
	cache map[string]struct {
		Answers    []dns.RR
		Expiration time.Time
	}
}

func (m *Memory) init(clear bool) {
	if m.cache == nil || clear {
		m.Lock()
		m.cache = nil
		m.cache = make(map[string]struct {
			Answers    []dns.RR
			Expiration time.Time
		})
		m.Unlock()
	}
}

func (m *Memory) PurgeAll() { m.init(true) }

func (m *Memory) Purge(name string) {
	m.Lock()
	defer m.Unlock()
	delete(m.cache, name)
}

func (m *Memory) LookupRecord(name string) []dns.RR {
	m.init(false)

	if v, ok := m.cache[name]; ok && time.Until(v.Expiration) > 0 {
		return v.Answers
	}

	return nil
}

func (m *Memory) SaveAnswers(name string, answers []dns.RR) {
	if answers == nil || name == "" {
		return
	}
	m.init(false)

	m.Lock()
	defer m.Unlock()
	ttl := time.Second * time.Duration(answers[0].Header().Ttl)
	m.cache[name] = struct {
		Answers    []dns.RR
		Expiration time.Time
	}{Answers: answers, Expiration: time.Now().Add(ttl)}
}
