package http

import (
	"fmt"

	"github.com/pocketbase/pocketbase/core"
)

// Своё правило ограничителя частоты под корнем приложения.
//
// Заводится потому, что правило хранилища настроено на **его** корень и наших
// адресов больше не покрывает: приложение уехало в своё пространство, и вместе с
// переездом ограничитель перестал бы существовать для него вовсе. Потеря тихая —
// заметить её нечем, пока кто-нибудь не начнёт опрашивать карточку в цикле.
//
// Числа скромные намеренно: сервисом пользуются единицы человек, а экран
// опрашивает карточку, пока запись идёт по конвейеру. Из них же выводится
// частота опроса, которую сервис объявляет приложению, — два числа об одном и
// том же разъехались бы при первой правке.
const (
	appRateMaxRequests = 120
	appRateWindowSec   = 60
)

// ApplyAppRateLimit ставит правило ограничителя на корень приложения.
//
// Правило приводится к настройке при каждом подъёме, как и настройки провайдера:
// применённый шаг схемы не переписывается, а настройки хранилища живут в базе, и
// правило, положенное однажды, не пережило бы ни правки числа, ни чистого
// каталога данных.
func ApplyAppRateLimit(app core.App) error {
	settings := app.Settings()

	rule := core.RateLimitRule{
		Label:       AppRoot + "/",
		MaxRequests: appRateMaxRequests,
		Duration:    appRateWindowSec,
	}

	replaced := false
	for i, existing := range settings.RateLimits.Rules {
		if existing.Label == rule.Label {
			settings.RateLimits.Rules[i] = rule
			replaced = true
			break
		}
	}
	if !replaced {
		settings.RateLimits.Rules = append(settings.RateLimits.Rules, rule)
	}

	settings.RateLimits.Enabled = true

	if err := app.Save(settings); err != nil {
		return fmt.Errorf("failed to apply app rate limit: %w", err)
	}
	return nil
}
