"""
Tests for scripts/token_tracker.py — Token Budget Tracker.
"""

import json
import os
import sqlite3
import tempfile
import unittest
from pathlib import Path

import sys
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
from token_tracker import (
    get_db,
    record_usage,
    get_usage_since,
    get_hourly_usage,
    get_worker_usage,
    format_tokens,
    progress_bar,
    estimate_eta,
    check_alerts,
    load_budgets,
    save_budgets,
)


class TestTokenTracker(unittest.TestCase):
    def setUp(self):
        self.tmpdir = tempfile.mkdtemp()
        self.db_path = Path(self.tmpdir) / "test.db"
        self.conn = get_db(self.db_path)

    def tearDown(self):
        self.conn.close()

    def test_record_usage(self):
        record_usage(self.conn, "pipeline1", "worker1", 1000)
        cursor = self.conn.execute("SELECT pipeline, worker, tokens FROM token_usage")
        row = cursor.fetchone()
        self.assertEqual(row, ("pipeline1", "worker1", 1000))

    def test_get_usage_since(self):
        record_usage(self.conn, "p1", "w1", 500)
        record_usage(self.conn, "p1", "w2", 300)
        record_usage(self.conn, "p2", "w1", 200)

        usage = get_usage_since(self.conn, "2020-01-01T00:00:00")
        self.assertEqual(usage["p1"], 800)
        self.assertEqual(usage["p2"], 200)

    def test_get_worker_usage(self):
        record_usage(self.conn, "p1", "w1", 500)
        record_usage(self.conn, "p1", "w2", 300)
        record_usage(self.conn, "p1", "w1", 100)

        workers = get_worker_usage(self.conn, "p1", "2020-01-01T00:00:00")
        self.assertEqual(workers["w1"], 600)
        self.assertEqual(workers["w2"], 300)


class TestFormatTokens(unittest.TestCase):
    def test_billions(self):
        self.assertEqual(format_tokens(1_500_000_000), "1.5B")

    def test_millions(self):
        self.assertEqual(format_tokens(45_200_000), "45.2M")

    def test_thousands(self):
        self.assertEqual(format_tokens(1_500), "1.5K")

    def test_small(self):
        self.assertEqual(format_tokens(42), "42")

    def test_zero(self):
        self.assertEqual(format_tokens(0), "0")


class TestProgressBar(unittest.TestCase):
    def test_empty(self):
        self.assertEqual(progress_bar(0, 100), "░" * 10)

    def test_half(self):
        bar = progress_bar(50, 100)
        self.assertEqual(bar, "█████░░░░░")

    def test_full(self):
        self.assertEqual(progress_bar(100, 100), "█" * 10)

    def test_overfull(self):
        self.assertEqual(progress_bar(150, 100), "█" * 10)

    def test_zero_target(self):
        self.assertEqual(progress_bar(0, 0), "░" * 10)


class TestEstimateEta(unittest.TestCase):
    def test_done(self):
        self.assertEqual(estimate_eta(100, 100, 1), "DONE")

    def test_hours(self):
        eta = estimate_eta(50, 100, 1)
        self.assertEqual(eta, "1.0h")

    def test_minutes(self):
        eta = estimate_eta(90, 100, 1)
        self.assertIn("m", eta)  # Should be in minutes format

    def test_no_data(self):
        self.assertEqual(estimate_eta(0, 100, 1), "N/A")


class TestCheckAlerts(unittest.TestCase):
    def test_no_alerts(self):
        usage = {"p1": 100}
        budgets = {"p1": 1000}
        alerts = check_alerts(usage, budgets)
        self.assertEqual(alerts, [])

    def test_50_percent(self):
        usage = {"p1": 500}
        budgets = {"p1": 1000}
        alerts = check_alerts(usage, budgets)
        self.assertTrue(any("50" in a for a in alerts))

    def test_80_percent(self):
        usage = {"p1": 800}
        budgets = {"p1": 1000}
        alerts = check_alerts(usage, budgets)
        self.assertTrue(any("80" in a for a in alerts))

    def test_100_percent(self):
        usage = {"p1": 1000}
        budgets = {"p1": 1000}
        alerts = check_alerts(usage, budgets)
        self.assertTrue(any("100" in a for a in alerts))

    def test_over_budget(self):
        usage = {"p1": 1500}
        budgets = {"p1": 1000}
        alerts = check_alerts(usage, budgets)
        self.assertTrue(len(alerts) >= 3)  # 50%, 80%, 100% all triggered
        self.assertTrue(any("🔴" in a for a in alerts))


class TestBudgets(unittest.TestCase):
    def test_save_load(self):
        tmpfile = tempfile.mktemp(suffix=".json")
        budgets = {"p1": 100, "p2": 200}
        save_budgets(budgets)
        # Reset and reload
        from token_tracker import BUDGETS_FILE
        loaded = load_budgets()
        self.assertIn("p1", loaded)


if __name__ == "__main__":
    unittest.main()
