/*
 * Copyright (C) 2025  Tim Zimmermann <tim@aglais.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.aglais.zms.ui.theme;

import org.aglais.zms.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.function.Consumer;

/**
 * A theme detector implementation specifically for the GNOME desktop environment
 * on Linux systems. This class detects whether the current GNOME theme is set to
 * dark mode by querying the GNOME settings through the gsettings command-line tool.
 * It also monitors changes to the theme settings and notifies registered listeners
 * when the theme changes between dark and light mode.
 * <p>
 * This class extends {@link OSThemeDetector} and provides a platform-specific
 * implementation for GNOME desktop environments.
 */
public class LinuxGNOMEOSThemeDetector extends OSThemeDetector {

    private static final String LOG_TAG = LinuxGNOMEOSThemeDetector.class.getSimpleName();
    private static final String GSETTINGS_CMD = "gsettings";
    private static final String DESKTOP_INTERFACE = "org.gnome.desktop.interface";
    private static final String KEY_COLOR_SCHEME = "color-scheme";
    private static final String VALUE_DARK = "prefer-dark";

    @Override
    public boolean isDark() {
        try {
            Process proc = Runtime.getRuntime().exec(new String[]{GSETTINGS_CMD, "get", DESKTOP_INTERFACE,
                    KEY_COLOR_SCHEME});
            BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = reader.readLine();

            return line != null && line.contains(VALUE_DARK);
        } catch (IOException ex) {
            Log.e(LOG_TAG, "Failed to get theme", ex);
        }

        return false;
    }

    @Override
    public void run() {
        try {
            Process proc = Runtime.getRuntime().exec(new String[]{GSETTINGS_CMD, "monitor", DESKTOP_INTERFACE,
                    KEY_COLOR_SCHEME});
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    if (line.startsWith(KEY_COLOR_SCHEME + ":")) {
                        boolean isDark = line.contains(VALUE_DARK);

                        for (Consumer<Boolean> listener : listeners) {
                            listener.accept(isDark);
                        }
                    }
                }
            }
        } catch (IOException ex) {
            Log.e(LOG_TAG, "Failed to monitor theme changes", ex);
        }
    }

}