#!/usr/bin/python3
import datetime
import subprocess
import sys
import time
from pathlib import Path
from zoneinfo import ZoneInfo

import gi

gi.require_version("Gio", "2.0")
from gi.repository import Gio, GLib


ROOT = Path(__file__).resolve().parent
sys.path.insert(0, str(ROOT / "calendar"))

from clockenstein.alarms import AlarmStore
from clockenstein import BUS_INTERFACE, BUS_NAME, BUS_PATH, SETTINGS_SCHEMA
from store import CalendarManager

TEST_ALARM_LABEL = "Clockenstein test alarm"
TEST_REMINDER_UID = "clockenstein-test-reminder"

def daemon_ready():
    connection = Gio.bus_get_sync(Gio.BusType.SESSION, None)
    for _attempt in range(50):
        result = connection.call_sync(
            "org.freedesktop.DBus", "/org/freedesktop/DBus",
            "org.freedesktop.DBus", "NameHasOwner", GLib.Variant("(s)", (BUS_NAME,)),
            GLib.VariantType.new("(b)"), Gio.DBusCallFlags.NONE, 1000, None,
        )
        if result.unpack()[0]:
            return
        time.sleep(0.1)
    raise SystemExit("The Clockenstein daemon did not start.")


def notify_daemon(method):
    try:
        connection = Gio.bus_get_sync(Gio.BusType.SESSION, None)
        connection.call_sync(
            BUS_NAME, BUS_PATH, BUS_INTERFACE, method, None, None,
            Gio.DBusCallFlags.NONE, 1000, None,
        )
    except GLib.Error as error:
        raise SystemExit(f"Could not contact the Clockenstein daemon: {error.message}")

def create_alarm(trigger):
    AlarmStore().create({
        "time": trigger.strftime("%H:%M"),
        "date": trigger.date().isoformat(),
        "label": TEST_ALARM_LABEL,
        "sound": "/usr/share/clockenstein/sounds/notification.oga",
        "sound_interval": 3,
    })
    notify_daemon("NotifyAlarmsChanged")


def create_reminder(store, trigger):
    lead_minutes = Gio.Settings.new(SETTINGS_SCHEMA).get_uint(
        "reminder-minutes"
    )
    start = trigger + datetime.timedelta(minutes=lead_minutes)
    store.create_event({
        "uid": TEST_REMINDER_UID,
        "summary": "Test reminder",
        "description": "Created by ./test-dummy-event",
        "all_day": False,
        "date_start": start.date(),
        "date_end": start.date(),
        "time_start": start.time().replace(tzinfo=None),
        "time_end": (start + datetime.timedelta(hours=1)).time().replace(tzinfo=None),
    })
    notify_daemon("NotifyChanged")


def clear_generated_events(store):
    alarms = AlarmStore()
    for alarm in alarms.list():
        if alarm.get("label") in ("Test alarm", TEST_ALARM_LABEL):
            alarms.delete(alarm["id"])
    for event in store.get_events(include_hidden=True):
        uid = event.get("uid", "")
        if uid.startswith("test-reminder-") or uid == TEST_REMINDER_UID:
            store.delete_event(
                event["uid"], event.get("calendar_id"), event.get("provider", "local"),
                event.get("account_id"),
            )

subprocess.run(["./dummy-events.sh"], check=True)
daemon_ready()
timezone = ZoneInfo(GLib.TimeZone.new_local().get_identifier())
now = datetime.datetime.now(timezone)
trigger = now.replace(second=0, microsecond=0) + datetime.timedelta(minutes=1)
store = CalendarManager(timezone)
clear_generated_events(store)
create_alarm(trigger)
create_reminder(store, trigger)

print(f"Test events scheduled for {trigger.strftime('%H:%M')}.")
