/*
 *  Copyright (c) 2022, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must strain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#include "power_updater.hpp"

#include "platform-posix.h"
#include <openthread/platform/radio.h>
#include "lib/platform/exit_code.h"

#if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE

namespace ot {
namespace Posix {

otError PowerUpdater::SetRegion(uint16_t aRegionCode)
{
    otError            error    = OT_ERROR_NONE;
    int                iterator = 0;
    Power::Domain      domain;
    Power::TargetPower targetPower;

    if (GetDomain(aRegionCode, domain) != OT_ERROR_NONE)
    {
        // If failed to find the domain for the region, use the world wide region as the default region.
        VerifyOrExit(GetDomain(kRegionCodeWorldWide, domain) == OT_ERROR_NONE, error = OT_ERROR_FAILED);
    }

    while (GetNextTargetPower(domain, iterator, targetPower) == OT_ERROR_NONE)
    {
        otLogInfoPlat("Update target power: %s\r\n", targetPower.ToString().AsCString());

        for (uint8_t ch = targetPower.GetChannelStart(); ch <= targetPower.GetChannelEnd(); ch++)
        {
            SuccessOrExit(error = otPlatRadioSetChannelTargetPower(gInstance, ch, targetPower.GetTargetPower()));
        }
    }

    SuccessOrExit(error = UpdateCalibratedPower());

    mRegionCode = aRegionCode;

exit:
    if (error == OT_ERROR_NONE)
    {
        otLogInfoPlat("Set region \"%c%c\" successfully", (aRegionCode >> 8) & 0xff, (aRegionCode & 0xff));
    }
    else
    {
        otLogCritPlat("Set region \"%c%c\" failed, Error: %s", (aRegionCode >> 8) & 0xff, (aRegionCode & 0xff),
                      otThreadErrorToString(error));
    }

    return error;
}

otError PowerUpdater::UpdateCalibratedPower(void)
{
    otError                error    = OT_ERROR_NONE;
    int                    iterator = 0;
    char                   value[kMaxValueSize];
    Power::CalibratedPower calibratedPower;
    ConfigFile            *calibrationFile = &mFactoryConfigFile;

    SuccessOrExit(error = otPlatRadioClearCalibratedPowers(gInstance));

    // If the distribution of output power is large, the factory needs to measure the power calibration data
    // for each device individually, and the power calibration data will be written to the factory config file.
    // Otherwise, the power calibration data can be pre-configured in the product config file.
    if (calibrationFile->Get(kKeyCalibratedPower, iterator, value, sizeof(value)) != OT_ERROR_NONE)
    {
        calibrationFile = &mProductConfigFile;
    }

    iterator = 0;
    while (calibrationFile->Get(kKeyCalibratedPower, iterator, value, sizeof(value)) == OT_ERROR_NONE)
    {
        SuccessOrExit(error = calibratedPower.FromString(value));
        otLogInfoPlat("Update calibrated power: %s\r\n", calibratedPower.ToString().AsCString());

        for (uint8_t ch = calibratedPower.GetChannelStart(); ch <= calibratedPower.GetChannelEnd(); ch++)
        {
            SuccessOrExit(error = otPlatRadioAddCalibratedPower(gInstance, ch, calibratedPower.GetActualPower(),
                                                                calibratedPower.GetRawPowerSetting().GetData(),
                                                                calibratedPower.GetRawPowerSetting().GetLength()));
        }
    }

exit:
    if (error != OT_ERROR_NONE)
    {
        otLogCritPlat("Update calibrated power table failed, Error: %s", otThreadErrorToString(error));
    }

    return error;
}

otError PowerUpdater::GetDomain(uint16_t aRegionCode, Power::Domain &aDomain)
{
    otError error    = OT_ERROR_NOT_FOUND;
    int     iterator = 0;
    char    value[kMaxValueSize];
    char   *str;

    while (mProductConfigFile.Get(kKeyRegionDomainMapping, iterator, value, sizeof(value)) == OT_ERROR_NONE)
    {
        if ((str = strtok(value, kCommaDelimiter)) == nullptr)
        {
            continue;
        }

        while ((str = strtok(nullptr, kCommaDelimiter)) != nullptr)
        {
            if ((strlen(str) == 2) && (StringToRegionCode(str) == aRegionCode))
            {
                ExitNow(error = aDomain.Set(value));
            }
        }
    }

exit:
    if (error != OT_ERROR_NONE)
    {
        otLogCritPlat("Get domain failed, Error: %s", otThreadErrorToString(error));
    }

    return error;
}

otError PowerUpdater::GetNextTargetPower(const Power::Domain &aDomain, int &aIterator, Power::TargetPower &aTargetPower)
{
    otError error = OT_ERROR_NOT_FOUND;
    char    value[kMaxValueSize];
    char   *domain;
    char   *psave;

    while (mProductConfigFile.Get(kKeyTargetPower, aIterator, value, sizeof(value)) == OT_ERROR_NONE)
    {
        if (((domain = strtok_r(value, kCommaDelimiter, &psave)) == nullptr) || (aDomain != domain))
        {
            continue;
        }

        if ((error = aTargetPower.FromString(psave)) != OT_ERROR_NONE)
        {
            otLogCritPlat("Read target power failed, Error: %s", otThreadErrorToString(error));
        }
        break;
    }

    return error;
}

} // namespace Posix
} // namespace ot
#endif // OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
