package de.gecheckt.pdf.umbenenner.application.dto;

/**
 * Token-Verbrauchsmetadaten eines erfolgreichen KI-Aufrufs.
 *
 * <p>Ein KI-Adapter befuellt dieses DTO mit den vom Provider zurueckgelieferten
 * Token-Zaehlungen. Alle Felder sind nullable: nicht alle Provider liefern
 * Cache-Tokens, und einzelne Felder koennen vom Adapter wegen ungueltiger
 * Werte (negativ, > 10 Mio., nicht-numerisch) auf {@code null} gesetzt werden.
 *
 * <p>Die Application-Schicht verwendet dieses DTO ohne JDBC- oder Domain-Bezug;
 * fuer die Persistenz werden die Werte vom {@code BatchRunProcessingUseCase}
 * direkt an den {@code ProcessingAttempt}-Schreibpfad weitergereicht.
 *
 * @param inputTokens               Anzahl Standard-Input-Tokens; {@code null} wenn nicht ermittelbar
 * @param outputTokens              Anzahl Standard-Output-Tokens; {@code null} wenn nicht ermittelbar
 * @param cacheCreationInputTokens  Anzahl Cache-Schreib-Tokens (nur Anthropic); {@code null} bei OpenAI-Adapter oder wenn nicht ermittelbar
 * @param cacheReadInputTokens      Anzahl Cache-Lese-Tokens (nur Anthropic); {@code null} bei OpenAI-Adapter oder wenn nicht ermittelbar
 */
public record AiUsageMetadata(
        Long inputTokens,
        Long outputTokens,
        Long cacheCreationInputTokens,
        Long cacheReadInputTokens) {

    /**
     * Liefert eine leere Instanz ohne jegliche Token-Daten.
     *
     * @return AiUsageMetadata mit allen Feldern auf {@code null}
     */
    public static AiUsageMetadata empty() {
        return new AiUsageMetadata(null, null, null, null);
    }

    /**
     * Pruefung, ob ueberhaupt Standard-Token-Daten vorliegen.
     *
     * <p>Maßgeblich fuer das Einschlusskriterium der Aggregations-Tabellen:
     * Eine Zeile fließt nur dann in die Kostenanalyse ein, wenn mindestens
     * eines der Standard-Tokenfelder gesetzt ist.
     *
     * @return {@code true} wenn {@link #inputTokens} oder {@link #outputTokens} gesetzt sind
     */
    public boolean hasAnyTokenData() {
        return inputTokens != null || outputTokens != null;
    }

    /**
     * Pruefung, ob Cache-Tokens (lesend oder schreibend) vorliegen.
     *
     * <p>Wird vom CostCalculator zur Setzung des {@code cacheTokensIgnored}-Flags
     * herangezogen, da V3.3 Cache-Tokens persistiert, aber nicht in die
     * Kostenberechnung einbezieht.
     *
     * @return {@code true} wenn ein Cache-Tokenfeld gesetzt und groeßer 0 ist
     */
    public boolean hasCacheTokens() {
        return (cacheCreationInputTokens != null && cacheCreationInputTokens > 0)
                || (cacheReadInputTokens != null && cacheReadInputTokens > 0);
    }
}
