/***********************************************************************
 *                                                                     *
 * Copyright 2016  Lorenzo Porta (Vindex17) <vindex17@outlook.it>      *
 *                                                                     *
 * 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 any later version accepted by the membership of      *
 * KDE e.V. (or its successor approved by the membership of KDE        *
 * e.V.), which shall act as a proxy defined in Section 14 of          *
 * version 3 of the license.                                           *
 *                                                                     *
 * 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 <http://www.gnu.org/licenses/> *
 *                                                                     *
 ***********************************************************************/


#pragma once


#include "exclusionwidget.hxx"
#include "logger.hxx"
#include "urlrequester.hxx"

#include <KIO/Job>
#include <KLocalizedString>
#include <QApplication>
#include <QCheckBox>
#include <QMainWindow>
#include <QPointer>
#include <QRadioButton>
#include <deque>
#include <functional>


struct KFolderSync : public QMainWindow
{
    explicit KFolderSync(QApplication * const) __attribute__((nonnull));
    Q_DISABLE_COPY(KFolderSync)

private:
    enum class Operation : std::int64_t {bilateral_differential_backup, bilateral_incremental_backup, differential_backup, incremental_backup, simple_backup, synchronization};
    struct FileMapEntryInfo {
        KIO::filesize_t size_in_destination, size_in_source;
        enum Match : std::int_fast8_t {
            no_info = 0,
            dir_vs_none = 1,
            file_vs_none = 2,
            none_vs_dir = 4,
            none_vs_file = 8,
            dir_vs_dir = dir_vs_none + none_vs_dir,
            dir_vs_file = dir_vs_none + none_vs_file,
            file_vs_dir = file_vs_none + none_vs_dir,
            file_vs_file = file_vs_none + none_vs_file,
        };
        std::underlying_type<Match>::type match;
        std::int_fast64_t relative_time;
    };
    struct Phase1Result {
        bool error;
        std::deque<std::pair<std::function<KIO::Job*()>,QString>> task_deque;
        explicit Phase1Result(const bool &&b = true) {error = b;}
    };

    ExclusionWidget exclusion_widget;
    Operation selected_operation = Operation::synchronization;
    QCheckBox include_hidden_files_checkbox {i18nc("@option:check", "Include hidden files")};
    QCheckBox interactive_mode_checkbox {i18nc("@option:check", "Interactive mode")};
    QCheckBox log_activity_checkbox {i18nc("@option:check imperative verb", "Log activity")};
    QCheckBox quit_when_finished_checkbox {i18nc("@option:check", "Quit when finished")};
    QCheckBox use_trash_checkbox {i18nc("@option:check", "Use the trash")};
    QPointer<Logger> logger;
    UrlRequester url_requester;
    const std::map<Operation,QRadioButton*> radiobutton_map;

    Phase1Result run_phase1(const QUrl &, const QUrl &) __attribute__((hot,warn_unused_result));
    QRadioButton * setup_radiobutton(const Operation &&, const QString &&, const QString &&, const QString &&) __attribute__((always_inline,warn_unused_result));
    void enable_logger(const bool &);
    void manage_profiles();
    void run() __attribute__((hot));
};
