/**
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
 * CANN Open Software License Agreement Version 2.0 (the "License").
 * Please refer to the License for details. You may not use this file except in compliance with the License.
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
 * See LICENSE in the root of the software repository for the full text of the License.
 */

#ifndef QS_ARGS_PARSER_H
#define QS_ARGS_PARSER_H

#include <string>
#include <vector>
#include <unordered_map>
#include "bqs_msg.h"

namespace bqs {
namespace {
const std::string PARAM_DEVICEID = "--deviceId=";
const std::string PARAM_HOST_PID = "--pid=";
const std::string PARAM_PIDSIGN = "--pidSign=";
const std::string PARAM_VFID = "--vfId=";
const std::string PARAM_LOGLEVEL = "--logLevelInPid=";
const std::string PARAM_AICPULOGLEVEL = "--aicpuLogLevel=";
const std::string PARAM_DEPLOY_MODE = "--deployMode=";
const std::string PARAM_RESCHED_INTERVAL = "--reschedInterval=";
const std::string PARAM_GRP_NAME = "--qsInitGroupName=";
const std::string PARAM_SCHED_POLICY = "--schedPolicy=";
const std::string PARAM_STARTER = "--starter=";
const std::string PARAM_PROF_CFG_DATA = "--profCfgData=";
const std::string PARAM_PROF_FLAG = "--profFlag=";
const std::string PARAM_ABNORMAL_INTERVAL = "--abnormalInterval=";
const std::string PARAM_RESOURCE_LIST = "--resIds=";
const std::string PARAM_DEVICEIDS_LIST = "--devIds=";
constexpr int32_t ERROR_LOG = 3;
constexpr int32_t EVENT_LOG = 1;
constexpr int32_t DEBUG_LOG = 0;
constexpr int32_t QS_FW_CHIP_NUM_MAX = 64;
constexpr int32_t VF_ID_MAX = 16;
constexpr int32_t VALUE_FOR_CALCULATE_LOG_LEVEL = 100;
constexpr int32_t SUCCESS_VALUE = 0;
constexpr int32_t RESCHED_INTERVAL_CLOSE = -1;
constexpr int32_t RESCHED_INTERVAL_DEFAULT = 30;
constexpr int32_t RESCHED_INTERVAL_MAX = 1000;
constexpr int32_t ABNORMAL_INTERVAL_MIN = 0;
constexpr int32_t ABNORMAL_INTERVAL_DEFAULT = 10;
constexpr int32_t ABNORMAL_INTERVAL_MAX = 1000;

} // namespace

class ArgsParser {
public:
    ArgsParser()
        : deviceId_(0U),
          hostPid_(0U),
          pidSign_(""),
          vfId_(0U),
          logLevel_(ERROR_LOG),
          eventLevel_(EVENT_LOG),
          aicpulogLevel_(-1),
          deployMode_(QueueSchedulerRunMode::SINGLE_PROCESS),
          reschedInterval_(RESCHED_INTERVAL_DEFAULT),
          groupName_(""),
          schedPolicy_(0U),
          starter_(QsStartType::START_BY_TSD),
          profCfgData_(""),
          abnormalInterval_(ABNORMAL_INTERVAL_DEFAULT),
          profFlag_(false),
          withDeviceId_(false),
          withHostPid_(false),
          withPidSign_(false),
          withVfId_(false),
          withLogLevel_(false),
          withGroupName_(false),
          withStarter_(false),
          argsParseFuncMap_(
              {{PARAM_DEVICEID, &ArgsParser::ParseDeviceId},
               {PARAM_HOST_PID, &ArgsParser::ParseHostPid},
               {PARAM_PIDSIGN, &ArgsParser::ParsePidSign},
               {PARAM_VFID, &ArgsParser::ParseVfId},
               {PARAM_LOGLEVEL, &ArgsParser::ParseLogAndEventLevel},
               {PARAM_AICPULOGLEVEL, &ArgsParser::ParseAicpuLogLevel},
               {PARAM_DEPLOY_MODE, &ArgsParser::ParseDeployMode},
               {PARAM_RESCHED_INTERVAL, &ArgsParser::ParseReschedInterval},
               {PARAM_GRP_NAME, &ArgsParser::ParseGroupName},
               {PARAM_SCHED_POLICY, &ArgsParser::ParseSchedPolicy},
               {PARAM_STARTER, &ArgsParser::ParseStarter},
               {PARAM_PROF_CFG_DATA, &ArgsParser::ParseProfCfgData},
               {PARAM_PROF_FLAG, &ArgsParser::ParseProfFlag},
               {PARAM_ABNORMAL_INTERVAL, &ArgsParser::ParseAbnormalInterval},
               {PARAM_RESOURCE_LIST, &ArgsParser::ParseResourceList},
               {PARAM_DEVICEIDS_LIST, &ArgsParser::ParseDeviceIdsList}}){};

    ~ArgsParser() = default;

    bool ParseArgs(const int32_t argc, const char_t* const argv[]);

    bool ParseArgs(const std::vector<std::string>& args);

    std::string GetParaParsedStr();

    inline uint32_t GetDeviceId() const { return deviceId_; }

    inline uint32_t GetHostPid() const { return hostPid_; }

    inline std::string GetPidSign() const { return pidSign_; }

    inline uint32_t GetVfId() const { return vfId_; }

    inline int32_t GetLogLevel() const { return logLevel_; }

    inline int32_t GetEventLevel() const { return eventLevel_; }

    inline int32_t GetAicpuLogLevel() const { return aicpulogLevel_; }

    inline QueueSchedulerRunMode GetDeployMode() const { return deployMode_; }

    inline int32_t GetReschedInterval() const { return reschedInterval_; }

    inline std::string GetGroupName() const { return groupName_; }

    inline uint64_t GetSchedPolicy() const { return schedPolicy_; }

    inline QsStartType GetStarter() const { return starter_; }

    inline std::string GetProfCfgData() const { return profCfgData_; }

    inline bool GetProfFlag() const { return profFlag_; }

    inline int32_t GetAbnormalInterval() const { return abnormalInterval_; }

    inline bool GetWithDeviceId() const { return withDeviceId_; }

    inline bool GetWithHostPid() const { return withHostPid_; }

    inline bool GetWithPidSign() const { return withPidSign_; }

    inline bool GetWithVfId() const { return withVfId_; }

    inline bool GetWithLogLevel() const { return withLogLevel_; }

    inline bool GetWithGroupName() const { return withGroupName_; }

    inline bool GetWithStarter() const { return withStarter_; }

    inline std::vector<uint32_t> GetResvec() const { return resVec_; }

    inline std::vector<uint32_t> GetDevIdVec() const { return devIdVec_; }

    void SetLogLevel(const int32_t logLevel, const int32_t eventLevel) const;

private:
    bool CheckRequiredParas() const;
    bool ParseSinglePara(const std::string& singlePara);
    bool ParseDeviceId(const std::string& para);
    bool ParseDeviceId(const std::string& para, int32_t& deviceId) const;
    bool ParseHostPid(const std::string& para);
    bool ParsePidSign(const std::string& para);
    bool ParseLogAndEventLevel(const std::string& para);
    bool ParseAicpuLogLevel(const std::string& para);
    bool ParseVfId(const std::string& para);
    bool ParseDeployMode(const std::string& para);
    bool ParseReschedInterval(const std::string& para);
    bool ParseGroupName(const std::string& para);
    bool ParseSchedPolicy(const std::string& para);
    bool ParseStarter(const std::string& para);
    bool ParseProfCfgData(const std::string& para);
    bool ParseProfFlag(const std::string& para);
    bool ParseAbnormalInterval(const std::string& para);
    bool ParseResourceList(const std::string& para);
    bool ParseDeviceIdsList(const std::string& para);
    void SetAicpuLogLevel() const;

    ArgsParser(ArgsParser const&) = delete;
    ArgsParser& operator=(ArgsParser const&) = delete;
    ArgsParser(ArgsParser&&) = delete;
    ArgsParser& operator=(ArgsParser&&) = delete;

    uint32_t deviceId_;
    uint32_t hostPid_;
    std::string pidSign_;
    uint32_t vfId_;
    int32_t logLevel_;
    int32_t eventLevel_;
    int32_t aicpulogLevel_;
    QueueSchedulerRunMode deployMode_;
    int32_t reschedInterval_;
    std::string groupName_;
    uint64_t schedPolicy_;
    QsStartType starter_;
    std::string profCfgData_;
    int32_t abnormalInterval_;
    std::vector<uint32_t> resVec_;
    std::vector<uint32_t> devIdVec_;
    bool profFlag_;
    bool withDeviceId_;
    bool withHostPid_;
    bool withPidSign_;
    bool withVfId_;
    bool withLogLevel_;
    bool withGroupName_;
    bool withStarter_;
    using SingleParaParseFunc = bool (ArgsParser::*)(const std::string&);
    const std::unordered_map<std::string, SingleParaParseFunc> argsParseFuncMap_;
};
} // namespace bqs

#endif // QS_ARGS_PARSER_H