#!/usr/bin/env python3
import json
import os
import subprocess
import sys
from pathlib import Path

from PyQt5 import QtCore, QtWidgets


APP_TITLE = "SAIKYO OS — Security Profile Manager"


def _run(cmd, check=False):
    return subprocess.run(cmd, check=check)


def _pkexec(cmd):
    # pkexec will prompt for admin auth via polkit
    return _run(["/usr/bin/pkexec"] + cmd, check=False)


def _profiles_dir() -> Path:
    return Path("/usr/share/saikyo-security-profile/profiles")


def _read_profile(profile: str) -> dict:
    p = _profiles_dir() / f"{profile}.json"
    return json.loads(p.read_text(encoding="utf-8"))


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle(APP_TITLE)
        self.setMinimumSize(720, 480)

        root = QtWidgets.QWidget(self)
        self.setCentralWidget(root)

        self.profile_combo = QtWidgets.QComboBox()
        self.profile_combo.addItems(["standard", "secure"])

        self.apply_btn = QtWidgets.QPushButton("Применить")
        self.export_btn = QtWidgets.QPushButton("Экспорт...")
        self.import_btn = QtWidgets.QPushButton("Импорт...")
        self.reload_btn = QtWidgets.QPushButton("Обновить")

        self.preview = QtWidgets.QPlainTextEdit()
        self.preview.setReadOnly(True)
        self.preview.setLineWrapMode(QtWidgets.QPlainTextEdit.NoWrap)

        top = QtWidgets.QHBoxLayout()
        top.addWidget(QtWidgets.QLabel("Профиль:"))
        top.addWidget(self.profile_combo, 1)
        top.addWidget(self.apply_btn)
        top.addWidget(self.export_btn)
        top.addWidget(self.import_btn)
        top.addWidget(self.reload_btn)

        layout = QtWidgets.QVBoxLayout(root)
        layout.addLayout(top)
        layout.addWidget(self.preview, 1)

        self.apply_btn.clicked.connect(self.on_apply)
        self.export_btn.clicked.connect(self.on_export)
        self.import_btn.clicked.connect(self.on_import)
        self.reload_btn.clicked.connect(self.refresh_preview)
        self.profile_combo.currentTextChanged.connect(lambda _: self.refresh_preview())

        self.refresh_preview()

    def current_profile(self) -> str:
        return self.profile_combo.currentText().strip()

    def refresh_preview(self):
        prof_name = self.current_profile()
        try:
            data = _read_profile(prof_name)
            self.preview.setPlainText(json.dumps(data, indent=2, sort_keys=True) + "\n")
        except Exception as e:
            self.preview.setPlainText(f"Ошибка чтения профиля '{prof_name}': {e}\n")

    def _msg(self, title: str, text: str, icon=QtWidgets.QMessageBox.Information):
        m = QtWidgets.QMessageBox(self)
        m.setIcon(icon)
        m.setWindowTitle(title)
        m.setText(text)
        m.exec_()

    def on_apply(self):
        prof = self.current_profile()
        rc = _pkexec(["/usr/sbin/saikyo-security-profile", "apply", prof]).returncode
        if rc == 0:
            self._msg("Готово", f"Профиль '{prof}' применён.")
        else:
            self._msg("Ошибка", f"Не удалось применить профиль '{prof}'. Код: {rc}", QtWidgets.QMessageBox.Critical)

    def on_export(self):
        prof = self.current_profile()
        path, _ = QtWidgets.QFileDialog.getSaveFileName(
            self,
            "Экспорт профиля",
            str(Path.home() / f"{prof}.json"),
            "JSON (*.json);;All files (*)",
        )
        if not path:
            return

        try:
            # Export does not require root
            rc = _run(["/usr/sbin/saikyo-security-profile", "export", prof, path], check=False).returncode
            if rc == 0:
                self._msg("Готово", f"Профиль '{prof}' экспортирован в:\n{path}")
            else:
                self._msg("Ошибка", f"Не удалось экспортировать профиль '{prof}'. Код: {rc}", QtWidgets.QMessageBox.Critical)
        except Exception as e:
            self._msg("Ошибка", str(e), QtWidgets.QMessageBox.Critical)

    def on_import(self):
        prof = self.current_profile()
        path, _ = QtWidgets.QFileDialog.getOpenFileName(
            self,
            "Импорт профиля",
            str(Path.home()),
            "JSON (*.json);;All files (*)",
        )
        if not path:
            return

        # Validate JSON before asking for auth
        try:
            json.loads(Path(path).read_text(encoding="utf-8"))
        except Exception as e:
            self._msg("Ошибка", f"Некорректный JSON: {e}", QtWidgets.QMessageBox.Critical)
            return

        rc = _pkexec(["/usr/sbin/saikyo-security-profile", "import", prof, path]).returncode
        if rc == 0:
            self._msg("Готово", f"Профиль '{prof}' импортирован из:\n{path}")
            self.refresh_preview()
        else:
            self._msg("Ошибка", f"Не удалось импортировать профиль '{prof}'. Код: {rc}", QtWidgets.QMessageBox.Critical)


def main(argv):
    if not Path("/usr/sbin/saikyo-security-profile").exists():
        print("ERROR: /usr/sbin/saikyo-security-profile not found", file=sys.stderr)
        return 2

    if not Path("/usr/bin/pkexec").exists():
        print("ERROR: pkexec not found (install policykit-1)", file=sys.stderr)
        return 2

    app = QtWidgets.QApplication(list(argv))
    app.setApplicationName("saikyo-security-profile-gui")
    w = MainWindow()
    w.show()
    return app.exec_()


if __name__ == "__main__":
    raise SystemExit(main(sys.argv))
