/*
 * Copyright 2024 Bloomberg Finance LP
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <buildboxcommon_logging_commandline.h>

namespace buildboxcommon {

using ArgumentSpec = buildboxcommon::CommandLineTypes::ArgumentSpec;
using DataType = buildboxcommon::CommandLineTypes::DataType;
using TypeInfo = buildboxcommon::CommandLineTypes::TypeInfo;
using DefaultValue = buildboxcommon::CommandLineTypes::DefaultValue;

std::vector<CommandLineTypes::ArgumentSpec> loggingCommandLineSpec()
{
    std::vector<CommandLineTypes::ArgumentSpec> spec;

    std::stringstream logLevels;
    logLevels << "(";
    bool first = true;
    for (const auto &level : logging::stringToLogLevelMap()) {
        logLevels << (first ? "" : ", ") << level.first;
        first = false;
    }
    logLevels << ")";

    spec.emplace_back("log-level", "Log level " + logLevels.str(),
                      TypeInfo(DataType::COMMANDLINE_DT_STRING),
                      ArgumentSpec::O_OPTIONAL, ArgumentSpec::C_WITH_ARG,
                      DefaultValue("error"));
    spec.emplace_back("verbose", "Set log level to 'debug'",
                      TypeInfo(DataType::COMMANDLINE_DT_BOOL),
                      ArgumentSpec::O_OPTIONAL, ArgumentSpec::C_WITHOUT_ARG);

    return spec;
}

bool parseLoggingOptions(const CommandLine &cml, LogLevel &logLevel)
{
    logLevel = ERROR;

    if (cml.exists("log-level")) {
        const auto logLevelString = cml.getString("log-level").c_str();

        const auto &logLevelMap = logging::stringToLogLevelMap();
        const auto it = logLevelMap.find(logLevelString);
        if (it == logLevelMap.end()) {
            BUILDBOX_LOG_ERROR("Invalid log level: " << logLevelString);
            return false;
        }

        logLevel = it->second;
    }

    if (cml.exists("verbose")) {
        logLevel = DEBUG;
    }

    return true;
}

} // namespace buildboxcommon
