"""Tests for qpip.project_init."""

from __future__ import annotations

import io
import tempfile
import unittest
from pathlib import Path

from qpip.project_init import InitUsageError, run_init_command


class RunInitCommandTests(unittest.TestCase):
    def test_init_yes_writes_pyproject_and_readme(self) -> None:
        with tempfile.TemporaryDirectory() as tmp_dir:
            project_dir = Path(tmp_dir) / "My Demo Project"
            project_dir.mkdir()
            buffer = io.StringIO()

            exit_code = run_init_command(["init", "-y"], cwd=project_dir, output=buffer)

            self.assertEqual(exit_code, 0)
            self.assertTrue((project_dir / "pyproject.toml").exists())
            self.assertTrue((project_dir / "README.md").exists())
            content = (project_dir / "pyproject.toml").read_text(encoding="utf-8")
            self.assertIn('name = "my-demo-project"', content)
            self.assertIn("[tool.qpip.scripts]", content)
            self.assertIn('test = "python -m unittest discover -s tests -v"', content)
            self.assertIn("已创建 pyproject.toml, README.md", buffer.getvalue())

    def test_init_interactive_writes_prompted_values(self) -> None:
        with tempfile.TemporaryDirectory() as tmp_dir:
            project_dir = Path(tmp_dir) / "demo"
            project_dir.mkdir()
            buffer = io.StringIO()
            answers = iter([
                "demo-app",
                "1.2.3",
                "A demo project",
                ">=3.10",
                "Alice",
                "alice@example.com",
                "Apache-2.0",
                "",
            ])

            exit_code = run_init_command(
                ["init"],
                cwd=project_dir,
                output=buffer,
                input_func=lambda prompt: next(answers),
            )

            content = (project_dir / "pyproject.toml").read_text(encoding="utf-8")
            self.assertEqual(exit_code, 0)
            self.assertIn('name = "demo-app"', content)
            self.assertIn('version = "1.2.3"', content)
            self.assertIn('description = "A demo project"', content)
            self.assertIn('requires-python = ">=3.10"', content)
            self.assertIn('{ name = "Alice", email = "alice@example.com" }', content)
            self.assertIn('license = { text = "Apache-2.0" }', content)
            self.assertIn("[tool.qpip.scripts]", content)

    def test_init_can_be_cancelled(self) -> None:
        with tempfile.TemporaryDirectory() as tmp_dir:
            project_dir = Path(tmp_dir) / "demo"
            project_dir.mkdir()
            buffer = io.StringIO()
            answers = iter(["demo-app", "", "", "", "", "", "", "n"])

            exit_code = run_init_command(
                ["init"],
                cwd=project_dir,
                output=buffer,
                input_func=lambda prompt: next(answers),
            )

            self.assertEqual(exit_code, 1)
            self.assertFalse((project_dir / "pyproject.toml").exists())
            self.assertIn("已取消初始化。", buffer.getvalue())

    def test_init_refuses_to_overwrite_existing_pyproject(self) -> None:
        with tempfile.TemporaryDirectory() as tmp_dir:
            project_dir = Path(tmp_dir) / "demo"
            project_dir.mkdir()
            (project_dir / "pyproject.toml").write_text("[project]\nname='demo'\n", encoding="utf-8")

            with self.assertRaises(InitUsageError):
                run_init_command(["init", "-y"], cwd=project_dir, output=io.StringIO())

    def test_init_dry_run_prints_preview_without_writing_files(self) -> None:
        with tempfile.TemporaryDirectory() as tmp_dir:
            project_dir = Path(tmp_dir) / "demo"
            project_dir.mkdir()
            buffer = io.StringIO()

            exit_code = run_init_command(["init", "-y"], cwd=project_dir, output=buffer, dry_run=True)

            self.assertEqual(exit_code, 0)
            self.assertFalse((project_dir / "pyproject.toml").exists())
            self.assertIn("预览模式：不会写入文件。", buffer.getvalue())
            self.assertIn("[build-system]", buffer.getvalue())
            self.assertIn("[tool.qpip.scripts]", buffer.getvalue())


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