#ifndef LIBPROJECTMANAGER_H
#define LIBPROJECTMANAGER_H

#include <libConfig.h>

#include <QFileInfo>
#include <QObject>
#include <QStandardItemModel>

namespace Project {

    /**
     * @brief 项目解析过程异常
     */
    class ProjectException : public Config::ParseException { };

    /**
     * @brief 项目管理
     * 项目名称
     *  ==包名称
     *      ==文件名称
     *  ==包名称
     *      ==包名称
     */
    class ProjectManager
    {
    public:
        virtual ~ProjectManager() = default;

        /**
         * @brief 项目树结构模型
         * @return
         */
        virtual QStandardItemModel* model() const = 0;

        /**
         * @brief 获取项目配置
         * @return 配置实例
         */
        virtual Config::Configration* configraions() const = 0;

        /**
         * @brief 获取项目文件所在文件夹
         * @return
         */
        virtual QDir projectDir() const = 0;

        // 项目操作=========================================================
        /**
         * @brief 获取适用的项目文件后缀
         * @return
         */
        virtual QString suffix() const = 0;

        /**
         * @brief 获取项目文件的实际路径
         * @param project_dir
         * @param name
         * @return
         */
        virtual QString fmtedProjectPath(const QString &project_dir, const QString &name) const = 0;

        /**
         * @brief 载入项目组织文件
         * @param project_file 项目文件路径
         * @throw ProjectException*, ParseException*
         */
        virtual void openProject(const QString &project_file) = 0;
        /**
         * @brief 指定项目文件夹，建立项目文件，一个文件夹只能建立一个项目
         * @param project_dir 项目文件夹
         * @param name 项目文件名
         * @throw ProjectException*, ParseException*
         */
        virtual void newProject(const QString &project_dir, const QString &name) = 0;
        /**
         * @brief 关闭当前项目
         */
        virtual void closeProject() = 0;
        /**
         * @brief 项目出于打开状态
         * @return
         */
        virtual bool isOpen() const noexcept = 0;
        /**
         * @brief 修改状态，需要被保存
         * @return
         */
        virtual bool isModified() const noexcept = 0;

        /**
         * @brief save 保存当前项目
         * @throw ProjectException, ParseException
         */
        virtual void save() = 0;

        /**
         * @brief 获取项目名称
         * @return
         */
        virtual QString projectName() const = 0;
        /**
         * @brief 重置项目名称
         * @param name
         */
        virtual void resetProjectName(const QString& name) = 0;

        // 项目内容管理=======================================================
        /**
         * @brief 建立新的包路径
         * @param path_defs 包路径定义
         * @return
         */
        virtual QModelIndex newPackage(const QList<QString> &path_defs) = 0;
        /**
         * @brief 转换QModexIndex为逻辑路径
         * @param path
         * @return
         */
        virtual QStringList packagePath(const QModelIndex &path) const = 0;
        /**
         * @brief 在指定包路径下建立创建文本文件记录
         * @param package_appoint 指定包节点路径
         * @throw ProjectException
         */
        virtual QModelIndex signFile(const QModelIndex &package_appoint, const QString &name, const QString &path_on_disk) = 0;
        /**
         * @brief 重命名该节点名称
         * @param node
         * @param name
         */
        virtual void rename(const QModelIndex &node, const QString &name) = 0;
        /**
         * @brief 汇总该节点下管理的磁盘文件信息
         * @param node
         * @return
         */
        virtual QList<QModelIndex> filesGather(const QModelIndex &node) const = 0;
        /**
         * @brief 移动到新的分类中
         * @param node_frompath 移动的源文件节点路径
         * @param target_group 移动目标包路径
         * @return
         */
        virtual void moveTo(const QModelIndex &node_frompath, const QModelIndex &target_group, int index=-1) = 0;
        /**
         * @brief 删除指定的文件或者包组织节点
         * @param node_path 节点路径，包路径或文件路径
         * @throw ProjectException
         */
        virtual void deleteTarget(const QModelIndex &node_path) = 0;

        /**
         * @brief 获取所有指定后缀名的文件
         * @param suffix 后缀名类型
         * @return 文件集合
         */
        virtual QList<std::tuple<QString, QFileInfo>> filesWithEnds(const QString &suffix) const = 0;
        /**
         * @brief 查询节点文件信息，文件节点返回文件的info，包节点返回文简介的info
         * @param path 树节点路径
         * @return QFileInfo 文件或文件夹的info实例
         */
        virtual QFileInfo queryInfo(const QModelIndex &path) = 0;

        /**
         * @brief 通过文件反查获取ModelIndex
         * @param file
         * @return
         */
        virtual QModelIndex queryIndex(const QFileInfo &file) = 0;

    };


}

#endif // LIBPROJECTMANAGER_H
