import pytest
from unittest.mock import patch, mock_open, MagicMock
import os

from pipa.service.gengerate.common import (
    ask_number,
    quest_basic,
    write_title,
    load_yaml_config,
    opener,
)


@patch("questionary.text")
def test_ask_number_default(mock_text):
    mock_text.return_value.ask.return_value = ""
    assert ask_number("Test question", 10) == 10


@patch("questionary.text")
def test_ask_number_input(mock_text):
    mock_text.return_value.ask.return_value = "5"
    assert ask_number("Test question", 10) == 5


@patch("questionary.text")
def test_ask_number_invalid_input(mock_text):
    mock_text.return_value.ask.return_value = "invalid"
    with pytest.raises(SystemExit):
        ask_number("Test question", 10)


@patch("questionary.text")
@patch("questionary.select")
@patch("os.path.exists")
@patch("os.makedirs")
def test_quest_basic_emon(mock_makedirs, mock_exists, mock_select, mock_text):
    mock_text.side_effect = [
        MagicMock(ask=lambda: ""),  # workspace
        MagicMock(ask=lambda: ""),  # freq_record
        MagicMock(ask=lambda: "{cycles,instructions}:S"),  # events_record
        MagicMock(ask=lambda: "/mnt/hdd/share/emon/system_health_monitor"),  # mpp
    ]
    mock_select.side_effect = [
        MagicMock(ask=lambda: "No"),  # annotete
        MagicMock(ask=lambda: "emon"),  # stat
    ]
    mock_exists.return_value = False

    result = quest_basic()
    expected_result = {
        "workspace": "./",
        "freq_record": 999,
        "events_record": "{cycles,instructions}:S",
        "use_emon": True,
        "mpp": "/mnt/hdd/share/emon/system_health_monitor",
        "annotete": False,
    }
    assert result == expected_result


@patch("builtins.open", new_callable=mock_open)
def test_write_title(mock_file):
    file = mock_file()
    write_title(file)
    file.write.assert_called_once()
    assert (
        "# The script generated by PIPA-TREE is used to collect performance data."
        in file.write.call_args[0][0]
    )


@patch("builtins.open", new_callable=mock_open, read_data='workspace: "./"\n')
def test_load_yaml_config(mock_file):
    config = load_yaml_config("dummy_path.yaml")
    assert config == {"workspace": "./"}


@patch("os.open")
def test_opener(mock_open):
    mock_open.return_value = 3
    descriptor = opener("dummy_path", os.O_RDWR)
    mock_open.assert_called_once_with(path="dummy_path", flags=os.O_RDWR, mode=0o755)
    assert descriptor == 3


if __name__ == "__main__":
    pytest.main([__file__])
