"""Integration tests that need neither a Plasma session nor Qt dependencies."""
import os
import subprocess
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch

from archweather import autostart, core, main


class KDETests(unittest.TestCase):
    def test_autostart_enable_disable_does_not_touch_user_data(self):
        with tempfile.TemporaryDirectory() as tmp:
            data = Path(tmp) / "data"
            cfg = Path(tmp) / "config"
            (data / "applications").mkdir(parents=True)
            (data / "applications" / autostart.ENTRY).write_text("[Desktop Entry]\nExec=/foo/tray\n", encoding="utf8")
            (cfg / "autostart").mkdir(parents=True)
            (cfg / "autostart" / autostart.OLD_ENTRY).write_text("old", encoding="utf8")
            (cfg / "archweather").mkdir(parents=True)
            (cfg / "archweather" / "config.json").write_text('{"favorites":["Utrecht"]}')
            with patch.dict(os.environ, {"XDG_DATA_HOME": str(data), "XDG_CONFIG_HOME": str(cfg)}):
                self.assertFalse(autostart.enabled())
                autostart.enable()
                self.assertTrue(autostart.enabled())
                self.assertFalse((cfg / "autostart" / autostart.OLD_ENTRY).exists())
                self.assertEqual(main.main(["autostart", "status"]), 0)
                self.assertEqual(main.main(["autostart", "off"]), 0)
                self.assertFalse(autostart.enabled())
                self.assertTrue((cfg / "archweather" / "config.json").exists())

    def test_autostart_requires_installed_launcher(self):
        with tempfile.TemporaryDirectory() as tmp:
            with patch.dict(os.environ, {"XDG_DATA_HOME": tmp, "XDG_CONFIG_HOME": tmp}):
                with self.assertRaises(FileNotFoundError):
                    autostart.enable()

    def test_saved_location_retains_name(self):
        place = {"name": "Utrecht", "latitude": 52.1, "longitude": 5.1, "country_code": "NL"}
        query = "52.1,5.1"
        # resolve_place is pure logic, even if the Qt app cannot start in a headless CI system.
        saved = dict(place, query=query)
        self.assertEqual(core.display_place(saved), "Utrecht, NL")
        self.assertEqual(saved["query"], query)

    def test_desktop_launcher_templates_are_present(self):
        root = Path(__file__).resolve().parents[1]
        content = (root / "install.sh").read_text()
        for required in ("archweather-open", "archweather-tray", "OnlyShowIn=KDE;", "QSystemTrayIcon", "$AUTODIR/archweather-tray.desktop"):
            # The word QSystemTrayIcon appears in the pyside6 preflight check.
            self.assertIn(required, content)

    def test_mock_install_upgrades_autostart_and_preserves_history(self):
        # Exercises installer without changing host packages or requiring network/Qt.
        if os.geteuid() == 0:
            self.skipTest("Deze installatietest moet zonder root draaien")
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(__file__).resolve().parents[1]
            home = Path(tmp) / "user"
            fake = Path(tmp) / "fakebin"
            fake.mkdir(); home.mkdir()
            python = fake / "python"
            python.write_text("""#!/usr/bin/env bash
if [[ "$1" == "-m" && "$2" == "venv" && "${@: -1}" != "--help" ]]; then
  d="${@: -1}"
  mkdir -p "$d/bin"
  printf '#!/bin/sh\\nexit 0\\n' > "$d/bin/python"
  chmod +x "$d/bin/python"
fi
exit 0
""".replace("\\n", "\n"), encoding="utf8")
            python.chmod(0o755)
            konsole = fake / "konsole"
            konsole.write_text("#!/bin/sh\nexit 0\n")
            konsole.chmod(0o755)
            cfg = home / ".config"
            old = cfg / "autostart" / "archweather.desktop"
            old.parent.mkdir(parents=True)
            old.write_text("[Desktop Entry]\nExec=previous\n", encoding="utf8")
            history = home / ".local/share/archweather/history.sqlite3"
            history.parent.mkdir(parents=True)
            history.write_bytes(b"KEEP-ME")
            config = cfg / "archweather" / "config.json"
            config.parent.mkdir(parents=True)
            config.write_text('{"location":"Delft","favorites":["Gouda"]}')
            env = os.environ.copy()
            env.update(HOME=str(home), PATH=f"{fake}:{env['PATH']}", DISPLAY="", WAYLAND_DISPLAY="",
                       XDG_CONFIG_HOME=str(cfg), XDG_DATA_HOME=str(home / ".local/share"))
            def run_install(*args):
                result = subprocess.run(["bash", str(root / "install.sh"), "--no-start", *args],
                                        capture_output=True, text=True, env=env)
                self.assertEqual(result.returncode, 0, result.stderr + result.stdout)
            run_install()
            self.assertFalse(old.exists())
            self.assertTrue((cfg / "autostart/archweather-tray.desktop").exists())
            launcher = home / ".local/share/applications/archweather.desktop"
            self.assertIn("Terminal=false", launcher.read_text())
            self.assertIn("archweather-open", launcher.read_text())
            run_install("--no-autostart")
            self.assertFalse((cfg / "autostart/archweather-tray.desktop").exists())
            self.assertEqual(history.read_bytes(), b"KEEP-ME")
            self.assertIn("Gouda", config.read_text())

    def test_shell_scripts_valid(self):
        root = Path(__file__).resolve().parents[1]
        for file in ("install.sh", "enable-autostart.sh", "disable-autostart.sh", "uninstall.sh"):
            p = subprocess.run(["bash", "-n", str(root / file)], capture_output=True, text=True)
            self.assertEqual(p.returncode, 0, f"{file}: {p.stderr}")


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