//
// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include <DelegateOptions.hpp>
#include <armnn/utility/NumericCast.hpp>
#include <armnn/utility/StringUtils.hpp>

namespace armnnDelegate
{

DelegateOptions::DelegateOptions(armnn::Compute computeDevice,
                                 const std::vector<armnn::BackendOptions>& backendOptions,
                                 const armnn::Optional<armnn::LogSeverity> logSeverityLevel)
    : m_Backends({computeDevice}), m_RuntimeOptions(), m_LoggingSeverity(logSeverityLevel)
{
    m_RuntimeOptions.m_BackendOptions = backendOptions;
}

DelegateOptions::DelegateOptions(const std::vector<armnn::BackendId>& backends,
                                 const std::vector<armnn::BackendOptions>& backendOptions,
                                 const armnn::Optional<armnn::LogSeverity> logSeverityLevel)
    : m_Backends(backends), m_RuntimeOptions(), m_LoggingSeverity(logSeverityLevel)
{
    m_RuntimeOptions.m_BackendOptions = backendOptions;
}

DelegateOptions::DelegateOptions(armnn::Compute computeDevice,
                                 const armnn::OptimizerOptions& optimizerOptions,
                                 const armnn::Optional<armnn::LogSeverity>& logSeverityLevel,
                                 const armnn::Optional<armnn::DebugCallbackFunction>& func)
    : m_Backends({computeDevice}),
      m_RuntimeOptions(),
      m_OptimizerOptions(optimizerOptions),
      m_LoggingSeverity(logSeverityLevel),
      m_DebugCallbackFunc(func)
{
}

DelegateOptions::DelegateOptions(const std::vector<armnn::BackendId>& backends,
                                 const armnn::OptimizerOptions& optimizerOptions,
                                 const armnn::Optional<armnn::LogSeverity>& logSeverityLevel,
                                 const armnn::Optional<armnn::DebugCallbackFunction>& func)
    : m_Backends(backends),
      m_RuntimeOptions(),
      m_OptimizerOptions(optimizerOptions),
      m_LoggingSeverity(logSeverityLevel),
      m_DebugCallbackFunc(func)
{
}

DelegateOptions::DelegateOptions(char const* const* options_keys,
                                 char const* const* options_values,
                                 size_t num_options,
                                 void (*report_error)(const char*))
{
    armnn::IRuntime::CreationOptions runtimeOptions;
    armnn::OptimizerOptions optimizerOptions;
    bool internalProfilingState = false;
    armnn::ProfilingDetailsMethod internalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsWithEvents;
    arm::pipe::ProfilingOptions extProfilingParams;
    for (size_t i = 0; i < num_options; ++i)
    {
        // Process backends
        if (std::string(options_keys[i]) == std::string("backends"))
        {
            // The backend option is a comma separated string of backendIDs that needs to be split
            std::vector<armnn::BackendId> backends;
            char* dup = strdup(options_values[i]);
            char* pch = std::strtok(dup, ",");
            while (pch != NULL)
            {
                backends.push_back(pch);
                pch = strtok (NULL, ",");
            }
            this->SetBackends(backends);
        }
            // Process dynamic-backends-path
        else if (std::string(options_keys[i]) == std::string("dynamic-backends-path"))
        {
            runtimeOptions.m_DynamicBackendsPath = std::string(options_values[i]);
        }
            // Process logging level
        else if (std::string(options_keys[i]) == std::string("logging-severity"))
        {
            this->SetLoggingSeverity(options_values[i]);
        }
            // Process GPU backend options
        else if (std::string(options_keys[i]) == std::string("gpu-tuning-level"))
        {
            armnn::BackendOptions option("GpuAcc", {{"TuningLevel", atoi(options_values[i])}});
            runtimeOptions.m_BackendOptions.push_back(option);
        }
        else if (std::string(options_keys[i]) == std::string("gpu-mlgo-tuning-file"))
        {
            armnn::BackendOptions option("GpuAcc", {{"MLGOTuningFilePath", std::string(options_values[i])}});
            optimizerOptions.m_ModelOptions.push_back(option);
        }
        else if (std::string(options_keys[i]) == std::string("gpu-tuning-file"))
        {
            armnn::BackendOptions option("GpuAcc", {{"TuningFile", std::string(options_values[i])}});
            runtimeOptions.m_BackendOptions.push_back(option);
        }
        else if (std::string(options_keys[i]) == std::string("gpu-enable-profiling"))
        {
            runtimeOptions.m_EnableGpuProfiling = (*options_values[i] != '0');
        }
        else if (std::string(options_keys[i]) == std::string("gpu-kernel-profiling-enabled"))
        {
            armnn::BackendOptions option("GpuAcc", {{"KernelProfilingEnabled",
                                                     armnn::stringUtils::StringToBool(options_values[i])}});
            runtimeOptions.m_BackendOptions.push_back(option);
        }
        else if (std::string(options_keys[i]) == std::string("save-cached-network"))
        {
            armnn::BackendOptions option("GpuAcc", {{"SaveCachedNetwork",
                                                     armnn::stringUtils::StringToBool(options_values[i])}});
            optimizerOptions.m_ModelOptions.push_back(option);
        }
        else if (std::string(options_keys[i]) == std::string("cached-network-filepath"))
        {
            armnn::BackendOptions option("GpuAcc", {{"CachedNetworkFilePath", std::string(options_values[i])}});
            optimizerOptions.m_ModelOptions.push_back(option);
        }
            // Process GPU & CPU backend options
        else if (std::string(options_keys[i]) == std::string("enable-fast-math"))
        {
            armnn::BackendOptions modelOptionGpu("GpuAcc", {{"FastMathEnabled",
                                                             armnn::stringUtils::StringToBool(options_values[i])}});
            optimizerOptions.m_ModelOptions.push_back(modelOptionGpu);

            armnn::BackendOptions modelOptionCpu("CpuAcc", {{"FastMathEnabled",
                                                             armnn::stringUtils::StringToBool(options_values[i])}});
            optimizerOptions.m_ModelOptions.push_back(modelOptionCpu);
        }
            // Process CPU backend options
        else if (std::string(options_keys[i]) == std::string("number-of-threads"))
        {
            unsigned int numberOfThreads = armnn::numeric_cast<unsigned int>(atoi(options_values[i]));
            armnn::BackendOptions modelOption("CpuAcc", {{"NumberOfThreads", numberOfThreads}});
            optimizerOptions.m_ModelOptions.push_back(modelOption);
        }
            // Process reduce-fp32-to-fp16 option
        else if (std::string(options_keys[i]) == std::string("reduce-fp32-to-fp16"))
        {
            optimizerOptions.m_ReduceFp32ToFp16 = armnn::stringUtils::StringToBool(options_values[i]);
        }
            // Process reduce-fp32-to-bf16 option
        else if (std::string(options_keys[i]) == std::string("reduce-fp32-to-bf16"))
        {
            optimizerOptions.m_ReduceFp32ToBf16 = armnn::stringUtils::StringToBool(options_values[i]);
        }
            // Process debug-data
        else if (std::string(options_keys[i]) == std::string("debug-data"))
        {
            optimizerOptions.m_Debug = armnn::stringUtils::StringToBool(options_values[i]);
        }
            // Process memory-import
        else if (std::string(options_keys[i]) == std::string("memory-import"))
        {
            optimizerOptions.m_ImportEnabled = armnn::stringUtils::StringToBool(options_values[i]);
        }
            // Process enable-internal-profiling
        else if (std::string(options_keys[i]) == std::string("enable-internal-profiling"))
        {
            internalProfilingState = *options_values[i] != '0';
            optimizerOptions.m_ProfilingEnabled = internalProfilingState;
        }
            // Process internal-profiling-detail
        else if (std::string(options_keys[i]) == std::string("internal-profiling-detail"))
        {
            uint32_t detailLevel = static_cast<uint32_t>(std::stoul(options_values[i]));
            switch (detailLevel)
            {
                case 1:
                    internalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsWithEvents;
                    break;
                case 2:
                    internalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsOnly;
                    break;
                default:
                    internalProfilingDetail = armnn::ProfilingDetailsMethod::Undefined;
                    break;
            }
        }
            // Process enable-external-profiling
        else if (std::string(options_keys[i]) == std::string("enable-external-profiling"))
        {
            extProfilingParams.m_EnableProfiling = armnn::stringUtils::StringToBool(options_values[i]);
        }
            // Process timeline-profiling
        else if (std::string(options_keys[i]) == std::string("timeline-profiling"))
        {
            extProfilingParams.m_TimelineEnabled = armnn::stringUtils::StringToBool(options_values[i]);
        }
            // Process outgoing-capture-file
        else if (std::string(options_keys[i]) == std::string("outgoing-capture-file"))
        {
            extProfilingParams.m_OutgoingCaptureFile = options_values[i];
        }
            // Process incoming-capture-file
        else if (std::string(options_keys[i]) == std::string("incoming-capture-file"))
        {
            extProfilingParams.m_IncomingCaptureFile = options_values[i];
        }
            // Process file-only-external-profiling
        else if (std::string(options_keys[i]) == std::string("file-only-external-profiling"))
        {
            extProfilingParams.m_FileOnly = armnn::stringUtils::StringToBool(options_values[i]);
        }
            // Process counter-capture-period
        else if (std::string(options_keys[i]) == std::string("counter-capture-period"))
        {
            extProfilingParams.m_CapturePeriod = static_cast<uint32_t>(std::stoul(options_values[i]));
        }
            // Process profiling-file-format
        else if (std::string(options_keys[i]) == std::string("profiling-file-format"))
        {
            extProfilingParams.m_FileFormat = options_values[i];
        }
            // Process serialize-to-dot
        else if (std::string(options_keys[i]) == std::string("serialize-to-dot"))
        {
            this->SetSerializeToDot(options_values[i]);
        }
        else
        {
            throw armnn::Exception("Unknown option for the ArmNN Delegate given: " + std::string(options_keys[i]));
        }
    }

    this->SetRuntimeOptions(runtimeOptions);
    this->SetOptimizerOptions(optimizerOptions);
    this->SetInternalProfilingParams(internalProfilingState, internalProfilingDetail);
    this->SetExternalProfilingParams(extProfilingParams);
}
} // namespace armnnDelegate
