package repository

import (
	"context"
	"sync"
	"time"

	domrepo "gateway/internal/model/notification/domain/repository"
)

// MemoryIdempotencyCache is an in-process IdempotencyCache for tests.
type MemoryIdempotencyCache struct {
	mu   sync.RWMutex
	data map[string][]byte
}

func NewMemoryIdempotencyCache() domrepo.IdempotencyCache {
	return &MemoryIdempotencyCache{data: make(map[string][]byte)}
}

func (c *MemoryIdempotencyCache) Get(_ context.Context, key string) ([]byte, error) {
	c.mu.RLock()
	defer c.mu.RUnlock()
	v, ok := c.data[key]
	if !ok {
		return nil, nil
	}
	out := make([]byte, len(v))
	copy(out, v)
	return out, nil
}

func (c *MemoryIdempotencyCache) Set(_ context.Context, key string, value []byte, _ time.Duration) error {
	c.mu.Lock()
	defer c.mu.Unlock()
	dup := make([]byte, len(value))
	copy(dup, value)
	c.data[key] = dup
	return nil
}

// MemoryQuotaCounter is an in-process QuotaCounter for tests.
type MemoryQuotaCounter struct {
	mu   sync.Mutex
	data map[string]int64
}

func NewMemoryQuotaCounter() domrepo.QuotaCounter {
	return &MemoryQuotaCounter{data: make(map[string]int64)}
}

func (c *MemoryQuotaCounter) Incr(_ context.Context, key string, _ time.Duration) (int64, error) {
	c.mu.Lock()
	defer c.mu.Unlock()
	c.data[key]++
	return c.data[key], nil
}
