"""Unit tests for CLI commands."""

from pathlib import Path
from unittest.mock import Mock, patch

import pytest
import yaml
from click.testing import CliRunner

from flow.api.models import TaskConfig
from flow.cli.app import cli


@pytest.mark.skip(reason="Old init implementation tests - replaced with new init")
class TestCLIInitCommand:
    """Test 'flow init' command."""

    @pytest.fixture
    def runner(self):
        """Create Click test runner."""
        return CliRunner()

    def test_init_command_success(self, runner):
        """Test successful init command.
        
        GIVEN: User runs 'flow init'
        WHEN: Setup wizard completes successfully
        THEN: Exit code is 0
        """
        with patch('flow.cli.commands.init.run_setup_wizard') as mock_wizard:
            mock_wizard.return_value = True

            result = runner.invoke(cli, ['init'])

            assert result.exit_code == 0
            mock_wizard.assert_called_once()

    def test_init_command_cancelled(self, runner):
        """Test init command when user cancels.
        
        GIVEN: User runs 'flow init'
        WHEN: Setup wizard is cancelled
        THEN: Exit code is 1
        """
        with patch('flow.cli.commands.init.run_setup_wizard') as mock_wizard:
            mock_wizard.return_value = False

            result = runner.invoke(cli, ['init'])

            assert result.exit_code == 1
            mock_wizard.assert_called_once()

    def test_init_command_with_existing_config(self, runner, tmp_path, monkeypatch):
        """Test init command with existing configuration.
        
        GIVEN: Existing configuration file
        WHEN: User runs 'flow init' and chooses not to overwrite
        THEN: Setup is cancelled
        """
        # Create existing config
        config_dir = tmp_path / ".flow"
        config_dir.mkdir()
        config_file = config_dir / "config.yaml"
        config_file.write_text("api_key: existing_key\nproject: existing_project")

        # Mock home directory
        monkeypatch.setattr(Path, 'home', lambda: tmp_path)

        with patch('flow.cli.commands.init.AdaptiveSetupWizard') as mock_wizard_class:
            mock_wizard = Mock()
            mock_wizard.run.return_value = False
            mock_wizard_class.return_value = mock_wizard

            result = runner.invoke(cli, ['init'])

            assert result.exit_code == 1


class TestCLIExampleCommand:
    """Test 'flow example' command."""

    @pytest.fixture
    def runner(self):
        """Create Click test runner."""
        return CliRunner()

    def test_example_list_all(self, runner):
        """Test listing all available examples.
        
        GIVEN: User runs 'flow example' without arguments
        WHEN: Command executes
        THEN: All available examples are listed
        """
        result = runner.invoke(cli, ['example'])

        assert result.exit_code == 0
        assert "Available examples:" in result.output
        assert "minimal" in result.output
        assert "gpu-test" in result.output
        assert "system-info" in result.output
        assert "training" in result.output
        assert "Usage: flow example <name>" in result.output

    def test_example_show_minimal(self, runner):
        """Test showing minimal example.
        
        GIVEN: User runs 'flow example minimal'
        WHEN: Command executes
        THEN: Minimal example YAML is output
        """
        result = runner.invoke(cli, ['example', 'minimal'])

        assert result.exit_code == 0
        # Parse output as YAML to verify it's valid
        output_yaml = yaml.safe_load(result.output)
        assert output_yaml['name'] == 'minimal-example'
        assert output_yaml['instance_type'] == 'a100-80gb.sxm.1x'
        assert 'Hello from Flow SDK!' in output_yaml['command']
        assert 'hostname' in output_yaml['command']

    def test_example_show_gpu_test(self, runner):
        """Test showing GPU test example.
        
        GIVEN: User runs 'flow example gpu-test'
        WHEN: Command executes
        THEN: GPU test example YAML is output
        """
        result = runner.invoke(cli, ['example', 'gpu-test'])

        assert result.exit_code == 0
        output_yaml = yaml.safe_load(result.output)
        assert output_yaml['name'] == 'gpu-test'
        assert output_yaml['instance_type'] == 'a100-80gb.sxm.1x'
        assert 'nvidia-smi' in output_yaml['command']
        assert output_yaml['max_price_per_hour'] == 5.0

    def test_example_show_system_info(self, runner):
        """Test showing system info example.
        
        GIVEN: User runs 'flow example system-info'
        WHEN: Command executes
        THEN: System info example YAML is output
        """
        result = runner.invoke(cli, ['example', 'system-info'])

        assert result.exit_code == 0
        output_yaml = yaml.safe_load(result.output)
        assert output_yaml['name'] == 'system-info'
        assert output_yaml['instance_type'] == 'a100-80gb.sxm.1x'
        assert 'System Information' in output_yaml['command']
        assert 'nvidia-smi' in output_yaml['command']
        # Examples don't have resources field anymore

    def test_example_show_training(self, runner):
        """Test showing training example.
        
        GIVEN: User runs 'flow example training'
        WHEN: Command executes
        THEN: Notebook example YAML is output with ports
        """
        result = runner.invoke(cli, ['example', 'training'])

        assert result.exit_code == 0
        output_yaml = yaml.safe_load(result.output)
        assert output_yaml['name'] == 'basic-training'
        assert output_yaml['instance_type'] == 'a100-80gb.sxm.2x'
        assert 'Starting training job' in output_yaml['command']
        assert len(output_yaml.get('volumes', [])) == 2
        assert output_yaml['max_price_per_hour'] == 10.0

    def test_example_invalid_name(self, runner):
        """Test requesting invalid example.
        
        GIVEN: User runs 'flow example invalid'
        WHEN: Command executes
        THEN: Error is shown with available examples
        """
        result = runner.invoke(cli, ['example', 'invalid'])

        assert result.exit_code == 1
        assert "Unknown example: invalid" in result.output
        assert "Available: " in result.output
        assert "minimal" in result.output
        assert "gpu-test" in result.output
        assert "training" in result.output

    def test_example_output_redirection(self, runner, tmp_path):
        """Test example output can be redirected to file.
        
        GIVEN: User runs 'flow example minimal > config.yaml'
        WHEN: Output is captured
        THEN: Valid YAML can be saved
        """
        result = runner.invoke(cli, ['example', 'minimal'])

        assert result.exit_code == 0

        # Save to file
        config_file = tmp_path / "config.yaml"
        config_file.write_text(result.output)

        # Verify it can be loaded as TaskConfig
        config = TaskConfig.from_yaml(str(config_file))
        assert config.name == 'minimal-example'
        # Just check that it can be loaded
        assert config.instance_type == 'a100-80gb.sxm.1x'
        assert 'Hello from Flow SDK!' in config.command


