// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once


#include "tests/testinterface.h"

#include <QObject>
#include <QStringList>

class QProcess;
class QByteArray;

/**
 * Core tests for the application.
 */
class CoreTests final : public QObject
{
    Q_OBJECT

public:
    explicit CoreTests(const TestInterfacePtr &test, QObject *parent = nullptr);

private slots:
    void initTestCase();
    void cleanupTestCase();
    void init();
    void cleanup();

    void configPath();
    void readLog();
    void rotateLog();
    void pluginsDisabled();
    void commandHelp();
    void commandVersion();
    void badCommand();
    void badSessionName();
    void commandSession();

    void commandCatchExceptions();

    void commandExit();
    void commandEval();
    void commandEvalThrows();
    void commandEvalThrowsWithLineNumber();
    void commandEvalSyntaxError();
    void commandEvalArguments();
    void commandEvalEndingWithComment();
    void commandPrint();
    void commandAbort();
    void commandFail();
    void commandSource();

    void commandVisible();
    void commandToggle();
    void commandShowHide();
    void commandShowHideRapid();
    void commandShowAt();
    void commandFocused();

    void commandsUnicode();

    void commandsAddRead();
    void commandsWriteRead();
    void commandsReadUtf8ByDefault();
    void commandChange();

    void commandSetCurrentTab();

    void commandConfig();
    void commandToggleConfig();

    void commandDialog();
    void commandDialogCloseOnDisconnect();

    void commandMenuItems();

    void commandsPackUnpack();
    void commandsBase64();
    void commandsGetSetItem();

    void commandsChecksums();

    void commandEscapeHTML();

    void commandExecute();

    void commandSettings();

    void commandsEnvSetEnv();

    void commandSleep();

    void commandsData();

    void commandCurrentWindowTitle();

    void commandCopy();
    void commandClipboard();
    void commandHasClipboardFormat();

    void commandEdit();
    void commandEditItem();

    void commandGetSetCurrentPath();

    void commandSelectItems();

    void commandsExportImport();

    void commandsGetSetCommands();

    void commandsImportExportCommands();
    void commandsImportExportCommandsFixIndentation();

    void commandsAddCommandsRegExp();

    void commandScreenshot();

    void commandNotification();
    void commandNotificationUrgency();
    void commandNotificationPersistent();
    void commandPlaySound();

    void commandIcon();
    void commandIconTag();
    void commandIconTagColor();
    void commandLoadTheme();

    void commandDateString();

    void commandAfterMilliseconds();

    void commandAsync();

    void commandFilter();

    void commandMimeTypes();

    void commandUnload();
    void commandForceUnload();

    void commandServerLogAndLogs();

    void commandStats();
    void statsQObjectLeak();
    void statsItemPreview();

    void classByteArray();
    void classFile();
    void classDir();
    void classTemporaryFile();
    void classItemSelection();
    void classItemSelectionGetCurrent();
    void classItemSelectionByteArray();
    void classItemSelectionSort();
    void classSettings();
    void calledWithInstance();

    void pipingCommands();

    void chainingCommands();

    void configMaxitems();

    void keysAndFocusing();

    void navigationDefault();
    void navigationVi();
    void navigationEmacs();

    void selectItems();

    void moveItems();
    void deleteItems();
    void searchItems();
    void searchItemsAndSelect();
    void searchItemsAndCopy();
    void searchRowNumber();
    void searchAccented();
    void searchManyItems();
    void copyItems();
    void selectAndCopyOrder();
    void copyItemsNullCharacter();

    void sortAndReverse();

    void createTabDialog();

    void copyPasteCommands();

    void editItems();
    void createNewItem();
    void editNotes();
    void editHtml();

    void toggleClipboardMonitoring();

    void clipboardToItem();
    void itemToClipboard();
    void tabAdd();
    void tabRemove();
    void tabIcon();
    void action();
    void insertRemoveItems();
    void renameTab();
    void renameClipboardTab();
    void importExportTab();

    void removeAllFoundItems();

    void nextPrevious();

    void externalEditor();

    void nextPreviousTab();

    void itemPreview();

    void openAndSavePreferences();

    void pasteFromMainWindow();

    void tray();
    void menu();

    void traySearch();
    void trayPaste();
    void trayShowHideAction();
    void trayMenuToggleRapid();

    void pasteNext();

    // Options for tray menu.
    void configTrayTab();
    void configMove();
    void configTrayTabIsCurrent();

    void configAutostart();

    void envVariablePaths();

    void configTabs();

    void selectedItems();

    void shortcutCommand();
    void shortcutCommandOverrideEnter();
    void shortcutCommandMatchInput();
    void shortcutCommandMatchCmd();

    void shortcutCommandSelectedItemData();
    void shortcutCommandSetSelectedItemData();
    void shortcutCommandSelectedItemsData();
    void shortcutCommandSetSelectedItemsData();
    void shortcutCommandSelectedAndCurrent();
    void shortcutCommandMoveSelected();

    void automaticCommandIgnore();
    void automaticCommandRemove();
    void automaticCommandInput();
    void automaticCommandRegExp();
    void automaticCommandSetData();
    void automaticCommandOutputTab();
    void automaticCommandNoOutputTab();
    void automaticCommandChaining();
    void automaticCommandCopyToTab();
    void automaticCommandStoreSpecialFormat();
    void automaticCommandIgnoreSpecialFormat();

    void globalCommandInMenu();

    void scriptCommandLoaded();
    void scriptCommandAddFunction();
    void scriptCommandOverrideFunction();
    void scriptCommandEnhanceFunction();
    void scriptCommandEndingWithComment();
    void scriptCommandWithError();

    void scriptPaste();
    void scriptOnTabSelected();
    void scriptOnItemsRemoved();
    void scriptOnItemsAdded();
    void scriptOnItemsChanged();
    void scriptOnItemsLoaded();
    void scriptEventMaxRecursion();
    void scriptSlowCollectOverrides();

    void displayCommand();
    void displayCommandForMenu();

    void synchronizeInternalCommands();

    void utilityCommands();

    void setTabName();

    void showHideAboutDialog();
    void showHideClipboardDialog();
    void showHideItemDialog();
    void showHideLogDialog();
    void showHideActionHandlerDialog();

    void shortcutDialogAddShortcut();
    void shortcutDialogAddTwoShortcuts();
    void shortcutDialogChangeShortcut();
    void shortcutDialogSameShortcut();
    void shortcutDialogCancel();

    void actionDialogCancel();
    void actionDialogAccept();
    void actionDialogSelectionInputOutput();

    void exitConfirm();
    void exitNoConfirm();
    void exitStopCommands();
    void terminateActionRequestTerminate();
    void terminateActionRequestKill();

    void abortInputReader();

    void changeAlwaysOnTop();

    void networkTests();

    void pluginNotInstalled();

    void startServerAndRunCommand();

    void avoidStoringPasswords();
    void scriptsForPasswords();

    void currentClipboardOwner();
    void singleClipboardProvider();

    void saveLargeItem();

    void slowClipboard();
    void clipboardUriList();
    void clipboardMimeSizeLimit();
    void clipboardMimeSizeLimitConfig();

    void handleUnexpectedTypes();

    void expireTabs();
    void expireEncryptionPassword();
    void expireEncryptionPasswordOnConfigChange();

    void dragNDropItemOrder();
    void dragNDropItemToTabTree();
    void dragNDropTreeTab();
    void dragNDropTreeTabNested();
    void dragNDropTreeTabChildCollision();
    void dragNDropTreeTabPartialRenameFailure();
    void dragNDropTreeTabKeepsCollapsedState();

    void tabEncryption();
    void tabEncryptionPasswordNew();
    void tabEncryptionPasswordCurrent();
    void tabEncryptionPasswordRetry();
    void tabEncryptionPasswordRetryFail();
    void tabEncryptionPasswordAbortRetry();
    void tabEncryptionLargeItems();
    void tabEncryptionChangePassword();

    void exportImportNoPasswordTab();
    void exportImportNoPasswordSettingsOnly();
    void exportImportNoPasswordCommandsOnly();
    void exportImportPasswordTab();
    void exportImportPasswordSettingsOnly();
    void exportImportPasswordCommandsOnly();
    void exportImportErrors();

private:
    void navigationTestInit();
    void navigationTestDownUp(const QString &down, const QString &up);
    void navigationTestEndHome(const QString &end, const QString &home);
    void navigationTestEscapeEditor(const QString &esc, const QString &editor);
    void navigationTestEscapeSearch(const QString &esc, const QString &search);

    enum ExportFlags {
        ExportWithPassword = 1,
        ExportTab = 2,
        ExportSettings = 4,
        ExportCommands = 8
    };
    void exportImport(int flags);

    void clearServerErrors();
    int run(const QStringList &arguments, QByteArray *stdoutData = nullptr,
            QByteArray *stderrData = nullptr, const QByteArray &in = QByteArray(),
            const QStringList &environment = QStringList());
    bool hasTab(const QString &tabName);

    TestInterfacePtr m_test;
};
