<?php

namespace App\Models\Monitoring;

use Illuminate\Database\Eloquent\Model;

/**
 * Incidencia del límite de peticiones de la API.
 *
 * Una fila por IP, ventana y tipo de límite, con el máximo observado: una IP que se
 * pase mil veces en un minuto genera una fila, no mil. Ver known-issues MGR-008.
 */
class ApiRateEvent extends Model
{
    protected $table = 'api_rate_events';

    protected $fillable = [
        'ip',
        'license_token_id',
        'window_started_at',
        'limit_kind',
        'kind',
        'observed',
        'limit_value',
        'rejected',
        'host',
        'action',
        'plugin',
        'user_agent',
    ];

    protected $casts = [
        'window_started_at' => 'datetime',
        'observed' => 'integer',
        'limit_value' => 'integer',
        'rejected' => 'integer',
    ];

    public const KIND_WARNING = 'warning';
    public const KIND_BLOCKED = 'blocked';

    public const LIMIT_FAILURES = 'failures';
    public const LIMIT_REQUESTS = 'requests';

    /**
     * Límite POR TOKEN, el que se configura en cada licencia
     * (`license_tokens.rate_limit_per_minute`). Los otros dos son por IP y se
     * configuran en `config/api.php`. Ver known-issues MGR-013.
     */
    public const LIMIT_TOKEN = 'token';

    public function licenseToken()
    {
        return $this->belongsTo(\App\Models\Products\LicenseToken::class);
    }

    /** ¿Lo ha cortado el límite de la licencia, o el de la IP? */
    public function getEsDeTokenAttribute(): bool
    {
        return $this->limit_kind === self::LIMIT_TOKEN;
    }

    /** Porcentaje del tope alcanzado, para ordenar por gravedad. */
    public function getPercentAttribute(): int
    {
        if ($this->limit_value <= 0) {
            return 0;
        }

        return (int) round(($this->observed / $this->limit_value) * 100);
    }
}
