/*
 * 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;

/**
 * WindowsOSThemeDetector is a concrete implementation of OSThemeDetector that detects the current
 * theme setting on Windows operating systems. It checks the Windows registry to determine whether
 * the system is using a dark mode theme by querying the following registry key:
 * <p>
 * HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize\AppsUseLightTheme
 * <p>
 * If the AppsUseLightTheme value is 0, it indicates dark mode is enabled. Otherwise, light mode
 * is considered active. This class provides the specific implementation for Windows theme detection
 * as part of the platform-specific theme detection system.
 */
public class WindowsOSThemeDetector extends OSThemeDetector {

    private static final String LOG_TAG = WindowsOSThemeDetector.class.getSimpleName();
    private static final String REG_COMMAND = "reg.exe";
    private static final String REG_PATH = "HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
    private static final String REG_KEY = "AppsUseLightTheme";
    private static final String VALUE_DARK = "0x0";

    private boolean previousValue = isDark();

    @Override
    public boolean isDark() {
        try {
            Process proc = Runtime.getRuntime().exec(new String[] {REG_COMMAND, "query", REG_PATH, "/V", REG_KEY});
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
                String line;

                while ((line = reader.readLine()) != null) {
                    if (line.trim().startsWith(REG_KEY)) {
                        return line.trim().endsWith(VALUE_DARK);
                    }
                }
            }
        } catch (IOException e) {
            Log.e(LOG_TAG, "Failed to get theme", e);
        }

        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;
            }
        }
    }
}