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

#ifndef __BUILDER_CONFIG_H__
#define __BUILDER_CONFIG_H__

#include <vector>
#include <string>
#include <memory>
#include <json/json.h>
#include <yaml-cpp/yaml.h>

#include "KMBuilderConfigTypes.h"
#include "KMBuilderUtils.h"
#include "KMBuilderModule.h"

using namespace std;

/* 如果格式以不兼容的方式更改，则强制重新生成 */
#define CONFIG_CHECKSUM_VERSION "5"
#define CONFIG_CHECKSUM_CLEANUP_VERSION "1"
#define CONFIG_CHECKSUM_FINISH_VERSION "3"
#define CONFIG_CHECKSUM_BUNDLE_SOURCES_VERSION "1"
#define CONFIG_CHECKSUM_PLATFORM_VERSION "1"

#define GROUP_PREFIX_EXTENSION "Extension "
#define KEY_ADD_LD_PATH "add-ld-path"
#define KEY_AUTODELETE "autodelete"
#define KEY_DIRECTORY "directory"
#define KEY_DOWNLOAD_IF "download-if"
#define KEY_ENABLE_IF "enable-if"
#define KEY_MERGE_DIRS "merge-dirs"
#define KEY_NO_AUTODOWNLOAD "no-autodownload"
#define KEY_LOCALE_SUBSET "locale-subset"
#define KEY_SUBDIRECTORIES "subdirectories"
#define KEY_SUBDIRECTORY_SUFFIX "subdirectory-suffix"
#define KEY_VERSION "version"
#define KEY_VERSIONS "versions"

#define GROUP_APPLICATION "Application"
#define GROUP_RUNTIME "Runtime"
#define KEY_COMMAND "command"
#define KEY_NAME "name"
#define KEY_REQUIRED_KAIMING "required-kaiming"
#define KEY_RUNTIME "runtime"
#define KEY_SDK "sdk"
#define KEY_TAGS "tags"

#define GROUP_BUILD "Build"
#define KEY_BUILD_EXTENSIONS "built-extensions"

#define DEFAULT_BRANCH "stable"

#define SEPARATE_DIR "share/runtime/locale"

#define MODULE_CHECKSUM_VERSION "1"

#define YAML_TEMPLATE_PATH "/opt/kaiming-tools/config/template.yaml"

typedef struct
{
    vector<string> baseExtensions;
    vector<string> cleanup;
    vector<string> cleanupCommands;
    vector<string> cleanupPlatform;
    vector<string> cleanupPlatformCommands;
    vector<string> preparePlatformCommands;
    vector<string> finishArgs;
    vector<string> inheritExtensions;
    vector<string> inheritSdkExtensions;
    vector<string> sdkExtensions;
    vector<string> platformExtensions;
    vector<string> tags;
    map<string, any> attributeMap;
    map<string, shared_ptr<BuilderExtension>> addExtensions;
    map<string, shared_ptr<BuilderExtension>> addBuildExtensions;
    shared_ptr<KMBuildOptions> buildOptions;
} ConfigData;

class KMBuilderConfig
{
    friend class KMBuilderConfigJson;
    friend class KMBuilderConfigYaml;

public:
    KMBuilderConfig();
    ~KMBuilderConfig();

    virtual bool loadConfigFile(const string &) = 0;

    virtual any getAttribute(const string &name) = 0;

    const vector<shared_ptr<KMBuilderModule>> getModules();

    void loadCommit();

    const shared_ptr<ConfigData> getConfigData()
    {
        return m_configData;
    }

    void setDemarshalBaseDir(const std::string &demarshalBaseDir)
    {
        m_demarshalBaseDir = demarshalBaseDir;
    }

    std::string demarshalBaseDir() const
    {
        return m_demarshalBaseDir;
    }

private:
    string m_configFile;
    string m_configPath;
    shared_ptr<ConfigData> m_configData;
    vector<shared_ptr<KMBuilderModule>> m_modules;
    std::string m_demarshalBaseDir;
};

#endif