using GLib;

public class Settings : DBusServiceProxy 
{
    public signal void config_changed();
    public signal void settings_ready();

    private DBusService.Settings? dbus_settings;
    private Secret.Service secret_service;

    public Settings() {
        base();
        
        try {
            secret_service = Secret.Service.get_sync(Secret.ServiceFlags.OPEN_SESSION);

            this.dbus_settings = Bus.get_proxy_sync<DBusService.Settings>(BusType.SESSION, DBUS_NAME, DBUS_PATH);
            settings_ready();
        } catch (GLib.Error e) {
            warning("Failed to get secret service: %s", e.message);
        }
    }

    public string get_server_url() throws DBusServiceProxyError, GLib.Error {
        if (dbus_settings == null) {
            throw new DBusServiceProxyError.NOT_CONNECTED("Settings not connected");
        }
        return dbus_settings.server_u_r_l;
    }

    public void set_server_url(string url) throws Error, GLib.Error {
        if (dbus_settings == null) {
            throw new DBusServiceProxyError.NOT_CONNECTED("Settings not connected");
        }
        dbus_settings.server_u_r_l = url;
    }

    public string get_username() throws Error, GLib.Error {
        if (dbus_settings == null) {
            throw new DBusServiceProxyError.NOT_CONNECTED("Settings not connected");
        }
        return dbus_settings.username;
    }

    public void set_username(string username) throws Error, GLib.Error {
        if (dbus_settings == null) {
            throw new DBusServiceProxyError.NOT_CONNECTED("Settings not connected");
        }
        dbus_settings.username = username;
    }

    public void set_server(string url, string username) throws Error, GLib.Error {
        if (dbus_settings == null) {
            throw new DBusServiceProxyError.NOT_CONNECTED("Settings not connected");
        }
        dbus_settings.set_server(url, username);
    }

    private HashTable<string, string> password_attributes() {
        var attributes = new HashTable<string, string>(str_hash, str_equal);
        attributes["service"] = "net.buzzert.kordophonecd";
        attributes["target"] = "default";
        attributes["username"] = get_username();
        return attributes;
    }

    public string get_password() throws Error {
        var attributes = password_attributes();
        var password = secret_service.lookup_sync(null, attributes, null);
        if (password == null) {
            warning("No password found for user %s", get_username());
            return "";
        }
        
        return password.get_text();
    }

    public void set_password(string password) throws Error, GLib.Error {
        var attributes = password_attributes();
        bool result = secret_service.store_sync(
            null,
            attributes,
            Secret.COLLECTION_DEFAULT,
            "Kordophone Keystore",
            new Secret.Value(password, password.length, "text/plain"),
            null
        );

        if (!result) {
            warning("Failed to store password for user %s", get_username());
            throw new DBusServiceProxyError.PASSWORD_STORAGE("Failed to store password");
        }
    }
} 