#ifndef KMINSTANCE_H
#define KMINSTANCE_H

#include "KMConfig.h"
#include "KMFolder.h"

namespace fs = std::filesystem;

/**
 * KMInstance:
 * @brief : 开明运行上下文
 */
class KMInstance
{
public:
    KMInstance(const string &appId);
    virtual ~KMInstance() = default;

    const fs::path &getBaseDir() { return m_baseDir; }
    const fs::path &getAppDir() { return m_appDir; }

    const fs::path &getAppXdgRuntimePath() { return m_appXdgRuntimeDir; };
    const fs::path &getAppSharedTmpPath() { return m_appSharedTmp; }
    const fs::path &getAppLockFile() { return m_appLockFile; }

    void init();
    bool ensurePerIdPath();
    bool ensurePerIdPidFile();
    bool ensurePerAppPath();
    bool ensurePerAppShareTmp();
    bool ensurePerAppXdgRuntimePath();
    bool ensurePerIdInfoFile();

    int getAppLockFd() { return m_appLockFd; }
    const std::string& instanceId() const { return m_instanceId; }
    std::string instanceHostDir() const { return m_instancePath.string(); }
    int instanceLockFd() const { return m_instanceLockFd; }

    static bool ensurePerAppDevShm(const std::string& appid, int perAppDirLockFd, std::string& sharedDevShmOut, std::string& errMsg);
    static bool ensurePerAppTmp(const std::string& appid, int perAppDirLockFd, std::string& sharedTmpOut, std::string& errMsg);
    void clearUnusedInstances();

    /**
     * @brief : 获取所有实例
     * @return: vector<KMInstance> 返回
     */
    static vector<shared_ptr<KMInstance>> getAllInstances();

    /**
     * @brief : 判断实例是否有效并删除无效id
     * @param: instance id
     * @return: true 有效 false 无效
     */
    static bool isValidIntance(const string &id);

public:
    /**
     * @brief : 获取进程pid
     */
    int getPid();

    /**
     * @brief : 获取子进程pid
     */
    int getChildPid();

    /**
     * @brief : 获取instance id
     */
    string getInstanceId();

    /**
     * @brief : 获取app名称
     */
    string getApp();

    /**
     * @brief : 获取架构
     */
    string getArch();

    /**
     * @brief : 获取分支
     */
    string getBranch();

    /**
     * @brief : 获取commit
     */
    string getCommit();

    /**
     * @brief : 获取runtime
     */
    string getRuntime();

private:
    /**
     * initPrivate:
     * @brief : 初始化私有成员
     */
    void initPrivate();

    /**
     * getPidFromFile:
     * @brief : 获取子pid
     * @return: int 返回
     */
    int getPidFromFile();

    /**
     * getPidFromFile:
     * @brief : 获取进程pid
     * @return: int 返回
     */
    int getChildPidFromFile();

    /**
     * getInfoFromFile:
     * @brief : 获取info信息
     * @return: true 成功 false 失败
     */
    bool getInfoFromFile();

private:
    string m_appId;
    string m_instanceId;
    fs::path m_instancePath;
    fs::path m_baseDir;
    fs::path m_appDir;
    fs::path m_appSharedTmp;
    fs::path m_appLockFile;
    fs::path m_appXdgRuntimeDir;

    int m_appLockFd;
    int m_instanceLockFd;

    class Private;
    std::shared_ptr<Private> d;
};

#endif
