/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *    All rights reserved.
 *
 *    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 "AppOptions.h"

#include <app/server/CommissioningWindowManager.h>
#include <app/server/Server.h>

#include <string>

using namespace chip::ArgParser;

using chip::ArgParser::OptionDef;
using chip::ArgParser::OptionSet;
using chip::ArgParser::PrintArgError;

constexpr uint16_t kOptionMinCommissioningTimeout    = 0xFF02;
constexpr uint16_t kOptionEndUserSupportFilePath     = 0xFF03;
constexpr uint16_t kOptionNetworkDiagnosticsFilePath = 0xFF04;
constexpr uint16_t kOptionCrashFilePath              = 0xFF05;

static chip::Optional<std::string> sEndUserSupportLogFilePath;
static chip::Optional<std::string> sNetworkDiagnosticsLogFilePath;
static chip::Optional<std::string> sCrashLogFilePath;

bool AppOptions::IsEmptyString(const char * value)
{
    return (value == nullptr || strlen(value) == 0);
}

bool AppOptions::HandleOptions(const char * program, OptionSet * options, int identifier, const char * name, const char * value)
{
    bool retval = true;
    switch (identifier)
    {
    case kOptionMinCommissioningTimeout: {
        auto & commissionMgr = chip::Server::GetInstance().GetCommissioningWindowManager();
        commissionMgr.OverrideMinCommissioningTimeout(chip::System::Clock::Seconds16(static_cast<uint16_t>(atoi(value))));
        break;
    }
    case kOptionEndUserSupportFilePath: {
        if (!IsEmptyString(value))
        {
            sEndUserSupportLogFilePath.SetValue(value);
        }
        break;
    }
    case kOptionNetworkDiagnosticsFilePath: {
        if (!IsEmptyString(value))
        {
            sNetworkDiagnosticsLogFilePath.SetValue(value);
        }
        break;
    }
    case kOptionCrashFilePath: {
        if (!IsEmptyString(value))
        {
            sCrashLogFilePath.SetValue(value);
        }
        break;
    }
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", program, name);
        retval = false;
        break;
    }

    return retval;
}

OptionSet * AppOptions::GetOptions()
{
    static OptionDef optionsDef[] = {
        { "min_commissioning_timeout", kArgumentRequired, kOptionMinCommissioningTimeout },
        { "end_user_support_log", kArgumentRequired, kOptionEndUserSupportFilePath },
        { "network_diagnostics_log", kArgumentRequired, kOptionNetworkDiagnosticsFilePath },
        { "crash_log", kArgumentRequired, kOptionCrashFilePath },
        {},
    };

    static OptionSet options = {
        AppOptions::HandleOptions, optionsDef, "PROGRAM OPTIONS",
        "  --min_commissioning_timeout <value>\n"
        "       The minimum time in seconds during which commissioning session establishment is allowed by the Node.\n"
        "  --end_user_support_log <value>\n"
        "       The end user support log file to be used for diagnostic logs transfer.\n"
        "  --network_diagnostics_log <value>\n"
        "       The network diagnostics log file to be used for diagnostic logs transfer.\n"
        "  --crash_log <value>\n"
        "       The crash log file to be used for diagnostic logs transfer.\n"
    };

    return &options;
}

chip::Optional<std::string> AppOptions::GetEndUserSupportLogFilePath()
{
    return sEndUserSupportLogFilePath;
}

chip::Optional<std::string> AppOptions::GetNetworkDiagnosticsLogFilePath()
{
    return sNetworkDiagnosticsLogFilePath;
}

chip::Optional<std::string> AppOptions::GetCrashLogFilePath()
{
    return sCrashLogFilePath;
}
