package auth

import (
	"sync"

	"secondbit.org/uuid"
)

type Memstore struct {
	tokens             map[string]Token
	refreshTokenLookup map[string]string
	profileTokenLookup map[string][]string
	tokenLock          sync.RWMutex

	grants    map[string]Grant
	grantLock sync.RWMutex

	clients             map[string]Client
	profileClientLookup map[string][]uuid.ID
	clientLock          sync.RWMutex

	endpoints    map[string][]Endpoint
	endpointLock sync.RWMutex

	profiles    map[string]Profile
	profileLock sync.RWMutex
}

func NewMemstore() *Memstore {
	return &Memstore{
		tokens:              map[string]Token{},
		refreshTokenLookup:  map[string]string{},
		profileTokenLookup:  map[string][]string{},
		grants:              map[string]Grant{},
		clients:             map[string]Client{},
		profileClientLookup: map[string][]uuid.ID{},
		endpoints:           map[string][]Endpoint{},
		profiles:            map[string]Profile{},
	}
}

func (m *Memstore) lookupTokenByRefresh(token string) (string, error) {
	m.tokenLock.RLock()
	defer m.tokenLock.RUnlock()
	t, ok := m.refreshTokenLookup[token]
	if !ok {
		return "", ErrTokenNotFound
	}
	return t, nil
}

func (m *Memstore) lookupTokensByProfileID(id string) ([]string, error) {
	m.tokenLock.RLock()
	defer m.tokenLock.RUnlock()
	return m.profileTokenLookup[id], nil
}

func (m *Memstore) lookupClientsByProfileID(id string) []uuid.ID {
	m.clientLock.RLock()
	defer m.clientLock.RUnlock()
	c, ok := m.profileClientLookup[id]
	if !ok {
		return []uuid.ID{}
	}
	return c
}
