"""Tests for model push and model card generation."""

import pytest

from bilgeai.hub.model_card import generate_model_card
from bilgeai.hub.pusher import ModelPusher


class TestModelPusher:
    def test_init_default(self):
        pusher = ModelPusher()
        assert pusher._token is None
        assert pusher._api is None

    def test_init_with_token(self):
        pusher = ModelPusher(token="hf_test123")
        assert pusher._token == "hf_test123"

    def test_push_model_nonexistent_dir(self, tmp_path):
        pusher = ModelPusher()
        with pytest.raises(FileNotFoundError):
            pusher.push_model(
                model_dir=tmp_path / "nonexistent",
                repo_id="test/model",
            )

    def test_push_file_nonexistent(self, tmp_path):
        pusher = ModelPusher()
        with pytest.raises(FileNotFoundError):
            pusher.push_file(
                file_path=tmp_path / "nonexistent.bin",
                repo_id="test/model",
            )

    def test_get_api_requires_huggingface_hub(self):
        pusher = ModelPusher()
        # This will either work or raise ImportError
        try:
            pusher._get_api()
        except ImportError as e:
            assert "huggingface_hub" in str(e).lower() or "huggingface-hub" in str(e).lower()


class TestModelCard:
    def test_basic_card(self):
        card = generate_model_card(
            model_name="meta-llama/Llama-3-8B",
            config_dict={"lora_rank": 16, "learning_rate": 2e-4, "num_epochs": 3},
        )
        assert "Llama-3-8B" in card
        assert "BilgeAI" in card
        assert "---" in card  # YAML front matter
        assert "lora_rank" in card.lower() or "LoRA Rank" in card

    def test_card_with_results(self):
        card = generate_model_card(
            model_name="mistralai/Mistral-7B",
            config_dict={"lora_rank": 16},
            results={"best_loss": 0.5, "final_loss": 0.6, "total_steps": 1000},
        )
        assert "0.5" in card
        assert "Results" in card

    def test_card_with_hardware(self):
        card = generate_model_card(
            model_name="meta-llama/Llama-3-8B",
            config_dict={},
            hardware_dict={
                "cpu_name": "AMD Ryzen 9",
                "ram_total_gb": 64.0,
                "gpus": [{"name": "RTX 4090", "vram_gb": 24.0}],
            },
        )
        assert "AMD Ryzen 9" in card
        assert "RTX 4090" in card

    def test_card_with_dataset(self):
        card = generate_model_card(
            model_name="test/model",
            config_dict={},
            dataset_name="tatsu-lab/alpaca",
        )
        assert "tatsu-lab/alpaca" in card

    def test_card_yaml_front_matter(self):
        card = generate_model_card(
            model_name="meta-llama/Llama-3-8B",
            config_dict={},
            license_id="mit",
            tags=["custom-tag"],
        )
        lines = card.split("\n")
        assert lines[0] == "---"
        assert any("mit" in line for line in lines)
        assert any("custom-tag" in line for line in lines)

    def test_card_training_time_in_minutes(self):
        card = generate_model_card(
            model_name="test/model",
            config_dict={},
            results={"training_time_seconds": 7200.0},
        )
        assert "120.0 min" in card
