/* app/builder/KMBuildFinish.h
 *
 * Copyright (C) 2024 OpenKylin, Inc
 */

#ifndef __KMBUILDFINISH_H__
#define __KMBUILDFINISH_H__

#include <set>

#include "app/KMSubCommand.h"

/**
 * @brief 	 完成构建目录
 * @note	 供kaiming-builder构建流程中调用
 */
class KMBuildFinish : public KMSubCommand
{
    DECLARE_DYNCREATE(KMBuildFinish);

public:
    KMBuildFinish();
    virtual ~KMBuildFinish();

    int despose(int argc, char **argv) override;

private:
    void init(int argc, char **argv);
    int run();

    void parseOptionsToContext();
    void setOptionSharesContext();
    void setOptionSocketsContext();
    void setOptionDevicesContext();
    void setOptionFeaturesContext();
    void setOptionFilesystemContext();
    void setOptionEnvContext();
    void parseEnvFd();
    void parseEnvBlock(const char *data, std::size_t length);
    void setOptionOwnNameContext();
    bool verifyDbusName(const std::string &dbusName);
    void setOptionTalkNameContext();
    void setOptionSystemDbusContext();
    void setOptionGenericPolicyContext();
    void verifyPolicy(const std::string &policy, std::string &key, std::string &value);
    void setOptionPersistContext();

    void collectExports();
    bool getAllowedExports(const std::string &path, std::set<std::string> &allowedExtensions, std::set<std::string> &allowedPrefixes, bool &requireExactMatch);

    bool copyExports(const std::string &srcDir, const std::string &destDir, const std::string &srcPrefix, const std::set<std::string> &allowedPrefixes, const std::set<std::string> &allowedExtensions,
                     bool requireExactMatch, std::string &errMsg);

    static bool exportDir(const std::string &srcDir, const std::string &srcName, const std::string &srcRelPath, const std::string &destDir, const std::string &destName,
                          const std::set<std::string> &allowedPrefixes, const std::set<std::string> &allowedExtensions, bool requireExactMatch, std::string &errMsg);

    static bool nameMatchesOneWildcardPrefix(const std::string &name, const std::set<std::string> &allowedPrefixes, bool requireExactMatch);

    static std::string findCommandInPath(const std::string &path);

    void updateMetadata();

private:
    class Options;
    class Private;
    std::unique_ptr<Private> d;
};

#endif // !__KMBUILDFINISH_H__
