package auth

import (
	"errors"
	"time"

	"secondbit.org/uuid"
)

var (
	ErrGrantNotFound      = errors.New("Grant not found in GrantStore.")
	ErrGrantAlreadyExists = errors.New("Grant already exists in GrantStore.")
)

type Grant struct {
	Code        string
	Created     time.Time
	ExpiresIn   int32
	ClientID    uuid.ID
	Scope       string
	RedirectURI string
	State       string
}

type GrantStore interface {
	GetGrant(code string) (Grant, error)
	SaveGrant(grant Grant) error
	DeleteGrant(code string) error
}

func (m *Memstore) GetGrant(code string) (Grant, error) {
	m.grantLock.RLock()
	defer m.grantLock.RUnlock()
	grant, ok := m.grants[code]
	if !ok {
		return Grant{}, ErrGrantNotFound
	}
	return grant, nil
}

func (m *Memstore) SaveGrant(grant Grant) error {
	m.grantLock.Lock()
	defer m.grantLock.Unlock()
	_, ok := m.grants[grant.Code]
	if ok {
		return ErrGrantAlreadyExists
	}
	m.grants[grant.Code] = grant
	return nil
}

func (m *Memstore) DeleteGrant(code string) error {
	m.grantLock.Lock()
	defer m.grantLock.Unlock()
	_, ok := m.grants[code]
	if !ok {
		return ErrGrantNotFound
	}
	delete(m.grants, code)
	return nil
}
