/*
 * 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 KDE desktop environment
 * on Linux systems. This class detects whether the current KDE theme is set to
 * dark mode by querying the KDE settings through the kreadconfig5/kreadconfig6 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 KDE desktop environments.
 */
public class LinuxKDEOSThemeDetector extends OSThemeDetector {

    private static final String LOG_TAG = LinuxGNOMEOSThemeDetector.class.getSimpleName();
    private static final String KREADCONFIG5_CMD = "kreadconfig5";
    private static final String KREADCONFIG6_CMD = "kreadconfig6";
    private static final String VALUE_DARK = "dark";

    private final String[] kreadconfigCmd = {KREADCONFIG5_CMD, "--file", "kdeglobals", "--group", "General", "--key",
            "ColorScheme"};
    private boolean previousValue;

    /**
     * Create a new {@link LinuxKDEOSThemeDetector} instance
     */
    public LinuxKDEOSThemeDetector() {
        String version = System.getenv("KDE_SESSION_VERSION");
        if ("6".equals(version)) {
            kreadconfigCmd[0] = KREADCONFIG6_CMD;
        }

        previousValue = isDark();
    }

    @Override
    public boolean isDark() {
        try {

            Process proc = Runtime.getRuntime().exec(kreadconfigCmd);
            BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = reader.readLine();

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

        return false;
    }

    @Override
    @SuppressWarnings("BusyWait")
    public void run() {
        while (true) {
            boolean currentValue = isDark();

            if (currentValue != previousValue) {
                for (Consumer<Boolean> listener : listeners) {
                    listener.accept(currentValue);
                }
            }

            previousValue = currentValue;

            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                break;
            }
        }
    }

}