#!/usr/bin/env python3
import tkinter as tk
from tkinter import ttk
import subprocess
import json
import sys
import os

class KanaModel:
    def _run(self, args):
        cmd = ["kana"] + args
        try:
            res = subprocess.run(cmd, capture_output=True, text=True)
            if res.returncode == 0 and res.stdout:
                return json.loads(res.stdout)
        except Exception:
            pass
        return None

    def get_report(self):
        return self._run(["--security-report"])
        
    def get_status(self):
        return self._run(["--status"])
        
    def enroll(self, code):
        return self._run(["--enroll", code])

    def fix(self, control):
        return self._run(["--fix", control])

class KanaGUI:
    def __init__(self, root, model):
        self.root = root
        self.model = model
        self.root.title("Kana")
        
        self.controls = [
            ("disk_encryption", "Disk encryption"),
            ("screen_lock", "Screen lock"),
            ("firewall", "Firewall"),
            ("automatic_updates", "Automatic updates"),
            ("malware_protection", "Malware protection"),
            ("launch_at_login", "Starts at login"),
        ]
        self.rows = {}
        
        main_frame = ttk.Frame(root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        self.status_var = tk.StringVar()
        ttk.Label(main_frame, textvariable=self.status_var).grid(row=0, column=0, columnspan=4, sticky=tk.W, pady=(0, 10))
        
        row_idx = 1
        for control_id, label in self.controls:
            ttk.Label(main_frame, text=label).grid(row=row_idx, column=0, sticky=tk.W, pady=2)
            state_var = tk.StringVar(value="?")
            state_lbl = ttk.Label(main_frame, textvariable=state_var, width=10)
            state_lbl.grid(row=row_idx, column=1, sticky=tk.W, padx=10, pady=2)
            
            detail_var = tk.StringVar()
            detail_lbl = ttk.Label(main_frame, textvariable=detail_var, wraplength=400)
            detail_lbl.grid(row=row_idx, column=2, sticky=tk.W, pady=2)
            
            fix_btn = ttk.Button(main_frame, text="Fix", command=lambda c=control_id: self.do_fix(c))
            fix_btn.grid(row=row_idx, column=3, padx=10, pady=2)
            
            self.rows[control_id] = {
                "state_var": state_var, 
                "detail_var": detail_var,
                "fix_btn": fix_btn,
                "state_lbl": state_lbl,
                "detail_lbl": detail_lbl,
            }
            row_idx += 1
            
        ttk.Button(main_frame, text="Refresh", command=self.refresh).grid(row=row_idx, column=0, pady=10)
        
        enroll_frame = ttk.Frame(main_frame)
        enroll_frame.grid(row=row_idx+1, column=0, columnspan=4, sticky=tk.W)
        ttk.Label(enroll_frame, text="Code/Link:").pack(side=tk.LEFT)
        self.enroll_var = tk.StringVar()
        ttk.Entry(enroll_frame, textvariable=self.enroll_var, width=30).pack(side=tk.LEFT, padx=5)
        ttk.Button(enroll_frame, text="Enroll", command=self.do_enroll).pack(side=tk.LEFT)
        
        self.refresh()
        
    def do_fix(self, control_id):
        new_state = self.model.fix(control_id)
        if new_state:
            # Re-observe the specific state if returned
            pass
        self.refresh()
        
    def do_enroll(self):
        code = self.enroll_var.get().strip()
        if code:
            self.model.enroll(code)
            self.refresh()
            
    def refresh(self):
        status = self.model.get_status()
        if status:
            self.status_var.set(status.get("status_line", "Unknown status"))
            
        report = self.model.get_report()
        if report and "posture" in report:
            for control_id, row in self.rows.items():
                if control_id == "malware_protection":
                    state_info = report.get("malware_scan", {})
                    state = state_info.get("state", "unknown")
                    if state == "clean":
                        state = "enabled"
                    elif state == "detected":
                        state = "disabled"
                    detail = state_info.get("reason", "")
                else:
                    state_info = report["posture"].get(control_id, {})
                    state = state_info.get("state", "unknown")
                    detail = state_info.get("detail", "")
                
                # Clean up detail string
                if "run the following" in detail.lower():
                    detail = detail.replace("run the following", "do the following")
                
                if len(detail) > 120:
                    detail = detail[:117] + "..."
                row["detail_var"].set(detail)

                if state == "enabled":
                    row["state_var"].set("✔")
                    row["fix_btn"].state(["disabled"])
                elif state == "disabled":
                    row["state_var"].set("❌")
                    row["fix_btn"].state(["!disabled"])
                elif state == "pending":
                    row["state_var"].set("pending")
                    row["fix_btn"].state(["disabled"])
                else:
                    row["state_var"].set("?")
                    row["fix_btn"].state(["disabled"])

def main():
    root = tk.Tk()
    model = KanaModel()
    app = KanaGUI(root, model)
    root.mainloop()

if __name__ == "__main__":
    main()
