/* common/KMExecerWrap.h
 *
 * Copyright (C) 2023 OpenKylin, Inc
 */

#ifndef __KMEXECERWRAP_H__
#define __KMEXECERWRAP_H__

#include <memory>

#include "config.h"
#include "KMCommonTypePrivate.h"
#include "KMExecer.h"
#include "KMContext.h"

class KMExecerWrap : public KMExecer
{
public:
    KMExecerWrap(const std::map<std::string, std::string>& envs);
    virtual ~KMExecerWrap();

    bool setupBaseArgv(const std::string& runtimeFiles, const std::string& appidDir, const std::string& arch, KMRunFlags flags);

    void applyContextEnvVars(const std::shared_ptr<KMContext>& context);

    bool addExtensionArgs(const std::shared_ptr<KMMetaData>& metadata,
                          const KMRef& ref,
                          bool useLdSoCache,
                          const std::string& targetPath,
                          std::string& extensionOut,
                          std::string& ldPathOut);

    void extendLdPath(const std::string& prepend, const std::string& append);

    bool addAppInfoArgs(const std::string& appFiles,
                        const std::string& originalAppFiles,
                        const std::string& appCommitId,
                        const std::string& appExtensions,
                        const std::string& runtimeFiles,
                        const std::string& originalRuntimeFiles,
                        const std::string& runtimeCommitId,
                        const std::string& runtimeExtensions,
                        const std::string& appId,
                        const std::string& appBranch,
                        const KMRef& runtimeRef,
                        const std::string& appIdDir,
                        const std::shared_ptr<KMContext>& finalAppContext,
                        const std::shared_ptr<KMContext>& cmdlineContext,
                        bool sandbox,
                        bool build,
                        bool devel,
                        std::string& appInfoPathOut,
                        int instanceIdFd,
                        std::string& instanceIdHostDirOut,
                        std::string& errMsg);

    bool addEnvironmentArgs(const std::string& appInfoPath,
                            KMRunFlags flags,
                            const std::string& appid,
                            const std::shared_ptr<KMContext>& context,
                            const std::string& appIdDir,
                            const std::vector<std::string>& previousAppIdDirs,
                            int perAppDirLockFd,
                            std::shared_ptr<KMExports>& exportsOut,
                            std::string& errMsg);
    

    void populateRuntimeDir(const std::string& sharedXdgRuntimeDir);

    void envpToArgs();

    bool bundleArgs(int start, int end, bool oneArg);

    void setupChildFds();

private:
    ///////////////// static method area  /////////////////////
    static bool parseX11Display(const std::string &display, int &family, std::string &x11Socket, std::string &remoteHost, std::string &displayNrOut);
    static std::string getPulseaudioServer();
    static std::string getPulseaudioServerUserConfig(const std::string &path);
    static std::string parsePulseServer(const std::string &value, bool &remote);
    static std::string getCupsServerName();
    static bool cupsCheckServerIsSocket(const std::string &server);
    static std::string getCupsServerNameConfig(const std::string &path);
    static std::string extractUnixPathFromDbusAddress(const std::string &address);
    static std::string createProxySocket(const std::string &socket);

private:
    void setupUsrLinks(const std::string &runtimeFiles, const std::string &sysroot);
    void setTZDataArgs(const std::string &runtimeFiles);
    void setMonitorPathArgs(bool useSessionHelper);

    ///////////////addEnvironmentArgs begin///////////////////////////
    void appendContextFilesystem(const std::shared_ptr<KMContext> &context, const std::string &appid, const std::string &appIdDir, const KMExports &exports, const std::string &xdgDirsConf,
                                 bool homeAccess);
    void applyEnvAppid(const std::string &appIdDir);
    void appendExportsArgs(const KMExports &exports);
    bool addWaylandArgs();
    void addX11Args(bool allowed, KMContextShares shares);
    void addSshArgs();
    void addPulseaudioArgs(KMContextShares shares);
    void addPcscArgs();
    void addCupsArgs();
    void addGpgAgentArgs();
    bool addContextSessionDbusArgs(std::shared_ptr<KMExecerWrap> proxyArgBwrap, const std::shared_ptr<KMContext> &context, KMRunFlags flags, const std::string &appid);
    void addContextBusFilters(const std::shared_ptr<KMContext> &context, const std::string &appid, bool session_bus, bool sandboxed);
    bool addContextSystemDbusArgs(std::shared_ptr<KMExecerWrap> proxyArgBwrap, const std::shared_ptr<KMContext> &context, KMRunFlags flags);
    bool addContextA11yDbusArgs(std::shared_ptr<KMExecerWrap> proxyArgBwrap, const std::shared_ptr<KMContext> &context, KMRunFlags flags);
    bool startDbusProxy(std::shared_ptr<KMExecerWrap> proxyArgBwrap, const std::string &app_info_path);
    ///////////////addEnvironmentArgs end///////////////////////////

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

#endif // !__KMEXECERWRAP_H__
