/* SPDX-License-Identifier: GPL-3.0-or-later
 * SPDX-FileCopyrightText: 2022-2024 Soren Stoutner <soren@stoutner.com>
 *
 * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU 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 General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <https://www.gnu.org/licenses/>.
 */

// Application headers.
#include "Settings.h"
#include "UserAgentHelper.h"
#include "widgets/TabWidget.h"

// KDE Framework headers.
#include <KLocalizedString>

// Define the public database constants.
const QString UserAgentHelper::SYSTEM_DEFAULT_DATABASE = QLatin1String("System Default");
const QString UserAgentHelper::PRIVACY_BROWSER_DATABASE = QLatin1String("Privacy Browser");
const QString UserAgentHelper::WEB_ENGINE_DEFAULT_DATABASE = QLatin1String("WebEngine Default");
const QString UserAgentHelper::FIREFOX_LINUX_DATABASE = QLatin1String("Firefox Linux");
const QString UserAgentHelper::CHROMIUM_LINUX_DATABASE = QLatin1String("Chromium Linux");
const QString UserAgentHelper::FIREFOX_WINDOWS_DATABASE = QLatin1String("Firefox Windows");
const QString UserAgentHelper::CHROME_WINDOWS_DATABASE = QLatin1String("Chrome Windows");
const QString UserAgentHelper::EDGE_WINDOWS_DATABASE = QLatin1String("Edge Windows");
const QString UserAgentHelper::SAFARI_MACOS_DATABASE = QLatin1String("Safari macOS");

// Define the public user agent constants.
const QString UserAgentHelper::PRIVACY_BROWSER_USER_AGENT = QLatin1String("PrivacyBrowser/1.0");
const QString UserAgentHelper::FIREFOX_LINUX_USER_AGENT = QLatin1String("Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0");
const QString UserAgentHelper::CHROMIUM_LINUX_USER_AGENT = QLatin1String("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36");
const QString UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:148.0) Gecko/20100101 Firefox/148.0");
const QString UserAgentHelper::CHROME_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36");
const QString UserAgentHelper::EDGE_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36 Edg/145.0.0.0");
const QString UserAgentHelper::SAFARI_MACOS_USER_AGENT = QLatin1String("macOS: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Safari/605.1.15");

// Construct the class.
UserAgentHelper::UserAgentHelper() {
    // Populate the translated user agents.  Translated entries cannot be public static const.
    SYSTEM_DEFAULT_TRANSLATED = i18nc("User agents", "System default");
    PRIVACY_BROWSER_TRANSLATED = i18nc("User agents", "Privacy Browser");
    WEB_ENGINE_DEFAULT_TRANSLATED = i18nc("User agents", "WebEngine default");
    FIREFOX_LINUX_TRANSLATED = i18nc("User agents", "Firefox on Linux");
    CHROMIUM_LINUX_TRANSLATED = i18nc("User agents", "Chromium on Linux");
    FIREFOX_WINDOWS_TRANSLATED = i18nc("User agents", "Firefox on Windows");
    CHROME_WINDOWS_TRANSLATED = i18nc("User agents", "Chrome on Windows");
    EDGE_WINDOWS_TRANSLATED = i18nc("User agents", "Edge on Windows");
    SAFARI_MACOS_TRANSLATED = i18nc("User agents", "Safari on macOS");
}

QString UserAgentHelper::getDatabaseUserAgentNameFromTranslatedName(const QString &translatedUserAgentName)
{
    // Return the database user agent name.
    if (translatedUserAgentName == SYSTEM_DEFAULT_TRANSLATED) return SYSTEM_DEFAULT_DATABASE;  // System Default.
    else if (translatedUserAgentName == PRIVACY_BROWSER_TRANSLATED) return PRIVACY_BROWSER_DATABASE;  // Privacy Browser.
    else if (translatedUserAgentName == WEB_ENGINE_DEFAULT_TRANSLATED) return WEB_ENGINE_DEFAULT_DATABASE;  // WebEngine default.
    else if (translatedUserAgentName == FIREFOX_LINUX_TRANSLATED) return FIREFOX_LINUX_DATABASE;  // Firefox Linux.
    else if (translatedUserAgentName == CHROMIUM_LINUX_TRANSLATED) return CHROMIUM_LINUX_DATABASE;  // Chromium Linux.
    else if (translatedUserAgentName == FIREFOX_WINDOWS_TRANSLATED) return FIREFOX_WINDOWS_DATABASE;  // Firefox Windows.
    else if (translatedUserAgentName == CHROME_WINDOWS_TRANSLATED) return CHROME_WINDOWS_DATABASE;  // Chrome Windows.
    else if (translatedUserAgentName == EDGE_WINDOWS_TRANSLATED) return EDGE_WINDOWS_DATABASE;  // Edge Windows.
    else if (translatedUserAgentName == SAFARI_MACOS_TRANSLATED) return SAFARI_MACOS_DATABASE;  // Safari macOS.
    else return translatedUserAgentName;  // Return the custom user agent.
}

QString UserAgentHelper::getDatabaseUserAgentNameFromUserAgent(const QString &userAgent)
{
    // Return the database user agent name.
    if (userAgent == PRIVACY_BROWSER_USER_AGENT) return PRIVACY_BROWSER_DATABASE;  // Privacy Browser.
    else if (userAgent == TabWidget::webEngineDefaultUserAgent) return WEB_ENGINE_DEFAULT_DATABASE;  // WebEngine default.
    else if (userAgent == FIREFOX_LINUX_USER_AGENT) return FIREFOX_LINUX_DATABASE;  // Firefox Linux.
    else if (userAgent == CHROMIUM_LINUX_USER_AGENT) return CHROMIUM_LINUX_DATABASE;  // Chromium Linux.
    else if (userAgent == FIREFOX_WINDOWS_USER_AGENT) return FIREFOX_WINDOWS_DATABASE;  // Firefox Windows.
    else if (userAgent == CHROME_WINDOWS_USER_AGENT) return CHROME_WINDOWS_DATABASE;  // Chrome Windows.
    else if (userAgent == EDGE_WINDOWS_USER_AGENT) return EDGE_WINDOWS_DATABASE;  // Edge Windows.
    else if (userAgent == SAFARI_MACOS_USER_AGENT) return SAFARI_MACOS_DATABASE;  // Safari macOS.
    else return userAgent;  // Return the custom user agent.
}

int UserAgentHelper::getDomainSettingsUserAgentIndex(const QString &userAgentName)
{
    // Return the domain settings user agent index.
    if (userAgentName == SYSTEM_DEFAULT_DATABASE) return 0;  // System Default.
    else if (userAgentName == PRIVACY_BROWSER_DATABASE) return 1;  // Privacy Browser.
    else if (userAgentName == WEB_ENGINE_DEFAULT_DATABASE) return 2;  // WebEngine default.
    else if (userAgentName == FIREFOX_LINUX_DATABASE) return 3;  // Firefox Linux.
    else if (userAgentName == CHROMIUM_LINUX_DATABASE) return 4;  // Chromium Linux.
    else if (userAgentName == FIREFOX_WINDOWS_DATABASE) return 5;  // Firefox Windows.
    else if (userAgentName == CHROME_WINDOWS_DATABASE) return 6;  // Chrome Windows.
    else if (userAgentName == EDGE_WINDOWS_DATABASE) return 7;  // Edge Windows.
    else if (userAgentName == SAFARI_MACOS_DATABASE) return 8;  // Safari macOS.
    else return -1;  // Custom user agent.
}

QString UserAgentHelper::getUserAgentFromDatabaseName(const QString &userAgentDatabaseName)
{
    if (userAgentDatabaseName == PRIVACY_BROWSER_DATABASE) return PRIVACY_BROWSER_USER_AGENT;  // Privacy Browser.
    else if (userAgentDatabaseName == WEB_ENGINE_DEFAULT_DATABASE) return TabWidget::webEngineDefaultUserAgent;  // WebEngine default.
    else if (userAgentDatabaseName == FIREFOX_LINUX_DATABASE) return FIREFOX_LINUX_USER_AGENT;  // Firefox Linux.
    else if (userAgentDatabaseName == CHROMIUM_LINUX_DATABASE) return CHROMIUM_LINUX_USER_AGENT;  // Chromium Linux.
    else if (userAgentDatabaseName == FIREFOX_WINDOWS_DATABASE) return FIREFOX_WINDOWS_USER_AGENT;  // Firefox Windows.
    else if (userAgentDatabaseName == CHROME_WINDOWS_DATABASE) return CHROME_WINDOWS_USER_AGENT;  // Chrome Windows.
    else if (userAgentDatabaseName == EDGE_WINDOWS_DATABASE) return EDGE_WINDOWS_USER_AGENT;  // Edge Windows.
    else if (userAgentDatabaseName == SAFARI_MACOS_DATABASE) return SAFARI_MACOS_USER_AGENT;  // Safari macOS.
    else return userAgentDatabaseName;  // Return the custom user agent.
}

QString UserAgentHelper::getUserAgentFromTranslatedName(const QString &userAgentTranslatedName)
{
    if (userAgentTranslatedName == PRIVACY_BROWSER_TRANSLATED) return PRIVACY_BROWSER_USER_AGENT;  // Privacy Browser.
    else if (userAgentTranslatedName == WEB_ENGINE_DEFAULT_TRANSLATED) return TabWidget::webEngineDefaultUserAgent;  // WebEngine default.
    else if (userAgentTranslatedName == FIREFOX_LINUX_TRANSLATED) return FIREFOX_LINUX_USER_AGENT;  // Firefox on Linux.
    else if (userAgentTranslatedName == CHROMIUM_LINUX_TRANSLATED) return CHROMIUM_LINUX_USER_AGENT;  // Chromium on Linux.
    else if (userAgentTranslatedName == FIREFOX_WINDOWS_TRANSLATED) return FIREFOX_WINDOWS_USER_AGENT;  // Firefox on Windows.
    else if (userAgentTranslatedName == CHROME_WINDOWS_TRANSLATED) return CHROME_WINDOWS_USER_AGENT;  // Chrome on Windows.
    else if (userAgentTranslatedName == EDGE_WINDOWS_TRANSLATED) return EDGE_WINDOWS_USER_AGENT;  // Edge on Windows.
    else if (userAgentTranslatedName == SAFARI_MACOS_TRANSLATED) return SAFARI_MACOS_USER_AGENT;  // Safari on macOS.
    else return userAgentTranslatedName;  // Return the custom user agent.
}

QString UserAgentHelper::getResultingDomainSettingsUserAgent(const QString &rawUserAgent)
{
    // Return the resulting user agent.  If `System default` is selected, it looks up the default user agent from the settings.
    if (rawUserAgent == SYSTEM_DEFAULT_DATABASE) return getUserAgentFromDatabaseName(Settings::userAgent());  // Return the default user agent.
    else return getUserAgentFromDatabaseName(rawUserAgent);  // Return the domain user agent.
}

QString UserAgentHelper::getTranslatedUserAgentNameFromDatabaseName(const QString &userAgentName)
{
    // Return the translated user agent name.
    if (userAgentName == PRIVACY_BROWSER_DATABASE) return PRIVACY_BROWSER_TRANSLATED;  // Privacy Browser.
    else if (userAgentName == WEB_ENGINE_DEFAULT_DATABASE) return WEB_ENGINE_DEFAULT_TRANSLATED;  // WebEngine default.
    else if (userAgentName == FIREFOX_LINUX_DATABASE) return FIREFOX_LINUX_TRANSLATED;  // Firefox on Linux.
    else if (userAgentName == CHROMIUM_LINUX_DATABASE) return CHROMIUM_LINUX_TRANSLATED;  // Chromium on Linux.
    else if (userAgentName == FIREFOX_WINDOWS_DATABASE) return FIREFOX_WINDOWS_TRANSLATED;  // Firefox on Windows.
    else if (userAgentName == CHROME_WINDOWS_DATABASE) return CHROME_WINDOWS_TRANSLATED;  // Chrome on Windows.
    else if (userAgentName == EDGE_WINDOWS_DATABASE) return EDGE_WINDOWS_TRANSLATED;  // Edge on Windows.
    else if (userAgentName == SAFARI_MACOS_DATABASE) return SAFARI_MACOS_TRANSLATED;  // Safari on macOS.
    else return userAgentName;  // Return the custom user agent.
}
