# Code generated by sqlc. DO NOT EDIT.
# versions:
#   sqlc v1.29.0
# source: insert_single_task_status_counts_row.sql
import dataclasses
import datetime

import sqlalchemy
import sqlalchemy.ext.asyncio

from . import models


INSERT_SINGLE_TASK_STATUS_COUNTS_ROW = """-- name: insert_single_task_status_counts_row \\:exec
WITH new_values AS (
    -- Parameters passed from your Go application
    SELECT
        :p1\\:\\:TIMESTAMPTZ AS current_timepoint,
        :p2\\:\\:INTEGER AS current_queued,
        :p3\\:\\:INTEGER AS current_running,
        :p4\\:\\:INTEGER AS current_waiting,
        :p5\\:\\:INTEGER AS current_failed,
        :p6\\:\\:INTEGER AS current_success,
        :p7\\:\\:INTEGER AS current_lost
),
previous_latest AS (
    -- Get the most recent record from the table for relevant delta calculations
    SELECT
        queued AS prev_queued,
        success AS prev_success,
        failed AS prev_failed,
        lost AS prev_lost
    FROM hyrex_stats_task_status_counts
    ORDER BY timepoint DESC
    LIMIT 1
)
INSERT INTO hyrex_stats_task_status_counts (
    timepoint,
    queued,
    running,
    waiting,
    failed,
    success,
    lost,
    total,
    queued_delta,
    success_delta,
    failed_delta,
    lost_delta
)
SELECT
    nv.current_timepoint,
    nv.current_queued,
    nv.current_running,
    nv.current_waiting,
    nv.current_failed,
    nv.current_success,
    nv.current_lost,
    -- Calculate total directly from new values
    (nv.current_queued + nv.current_running + nv.current_waiting + nv.current_failed + nv.current_success + nv.current_lost) AS total_count,

    -- Calculate absolute deltas from the previous row
    -- If no previous row, prev_xxx will be NULL, (current - NULL) is NULL. COALESCE makes it 0.
    COALESCE(nv.current_queued - pl.prev_queued, 0) AS queued_delta,
    COALESCE(nv.current_success - pl.prev_success, 0) AS success_delta,
    COALESCE(nv.current_failed - pl.prev_failed, 0) AS failed_delta,
    COALESCE(nv.current_lost - pl.prev_lost, 0) AS lost_delta
FROM
    new_values nv
LEFT JOIN
    previous_latest pl ON TRUE -- Ensures new_values always processed; pl columns will be NULL if table is empty
ON CONFLICT (timepoint) DO UPDATE SET
    queued = EXCLUDED.queued,
    running = EXCLUDED.running,
    waiting = EXCLUDED.waiting,
    failed = EXCLUDED.failed,
    success = EXCLUDED.success,
    lost = EXCLUDED.lost,
    total = EXCLUDED.total,
    queued_delta = EXCLUDED.queued_delta,
    success_delta = EXCLUDED.success_delta,
    failed_delta = EXCLUDED.failed_delta,
    lost_delta = EXCLUDED.lost_delta
"""


@dataclasses.dataclass()
class InsertSingleTaskStatusCountsRowParams:
    timepoint: datetime.datetime
    queued: int
    running: int
    waiting: int
    failed: int
    success: int
    lost: int


class Querier:
    def __init__(self, conn: sqlalchemy.engine.Connection):
        self._conn = conn

    def insert_single_task_status_counts_row(self, arg: InsertSingleTaskStatusCountsRowParams) -> None:
        self._conn.execute(sqlalchemy.text(INSERT_SINGLE_TASK_STATUS_COUNTS_ROW), {
            "p1": arg.timepoint,
            "p2": arg.queued,
            "p3": arg.running,
            "p4": arg.waiting,
            "p5": arg.failed,
            "p6": arg.success,
            "p7": arg.lost,
        })


class AsyncQuerier:
    def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection):
        self._conn = conn

    async def insert_single_task_status_counts_row(self, arg: InsertSingleTaskStatusCountsRowParams) -> None:
        await self._conn.execute(sqlalchemy.text(INSERT_SINGLE_TASK_STATUS_COUNTS_ROW), {
            "p1": arg.timepoint,
            "p2": arg.queued,
            "p3": arg.running,
            "p4": arg.waiting,
            "p5": arg.failed,
            "p6": arg.success,
            "p7": arg.lost,
        })
