// Copyright (c) 2020 Intel Corporation
//
// 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 "speed_select.hpp"

#include "cpuinfo.hpp"
#include "cpuinfo_utils.hpp"

#include <peci.h>

#include <boost/asio/error.hpp>
#include <boost/asio/steady_timer.hpp>
#include <xyz/openbmc_project/Common/Device/error.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/Control/Processor/CurrentOperatingConfig/server.hpp>
#include <xyz/openbmc_project/Inventory/Item/Cpu/OperatingConfig/server.hpp>

#include <algorithm>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>

namespace cpu_info
{
namespace sst
{

// Specialize char to print the integer value instead of ascii. We basically
// never want to print a single ascii char.
std::ostream& operator<<(std::ostream& os, uint8_t value)
{
    return os << static_cast<int>(value);
}

bool checkPECIStatus(EPECIStatus libStatus, uint8_t completionCode)
{
    if (libStatus != PECI_CC_SUCCESS || completionCode != PECI_DEV_CC_SUCCESS)
    {
        std::cerr << "PECI command failed."
                  << " Driver Status = " << libStatus << ","
                  << " Completion Code = " << completionCode << '\n';
        return false;
    }
    return true;
}

std::vector<uint32_t> convertMaskToList(std::bitset<64> mask)
{
    std::vector<uint32_t> bitList;
    for (size_t i = 0; i < mask.size(); ++i)
    {
        if (mask.test(i))
        {
            bitList.push_back(i);
        }
    }
    return bitList;
}

static std::vector<BackendProvider>& getProviders()
{
    static auto* providers = new std::vector<BackendProvider>;
    return *providers;
}

void registerBackend(BackendProvider providerFn)
{
    getProviders().push_back(providerFn);
}

std::unique_ptr<SSTInterface> getInstance(uint8_t address, CPUModel model,
                                          WakePolicy wakePolicy)
{
    DEBUG_PRINT << "Searching for provider for " << address << ", model "
                << std::hex << model << std::dec << '\n';
    for (const auto& provider : getProviders())
    {
        try
        {
            auto interface = provider(address, model, wakePolicy);
            DEBUG_PRINT << "returned " << interface << '\n';
            if (interface)
            {
                return interface;
            }
        }
        catch (...)
        {}
    }
    DEBUG_PRINT << "No supported backends found\n";
    return nullptr;
}

using BaseCurrentOperatingConfig =
    sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project::
                                    control::processor::CurrentOperatingConfig>;

using BaseOperatingConfig =
    sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project::
                                    inventory::item::cpu::OperatingConfig>;

class OperatingConfig : public BaseOperatingConfig
{
  public:
    std::string path;
    unsigned int level;

  public:
    using BaseOperatingConfig::BaseOperatingConfig;
    OperatingConfig(sdbusplus::bus_t& bus, unsigned int level_,
                    std::string path_) :
        BaseOperatingConfig(bus, path_.c_str(), action::defer_emit),
        path(std::move(path_)), level(level_)
    {}
};

class CPUConfig : public BaseCurrentOperatingConfig
{
  private:
    /** Objects describing all available SST configs - not modifiable. */
    std::vector<std::unique_ptr<OperatingConfig>> availConfigs;
    sdbusplus::bus_t& bus;
    const uint8_t peciAddress;
    const std::string path; ///< D-Bus path of CPU object
    const CPUModel cpuModel;

    // Keep mutable copies of the properties so we can cache values that we
    // retrieve in the getters. We don't want to throw an error on a D-Bus
    // get-property call (extra error handling in clients), so by caching we can
    // hide any temporary hiccup in PECI communication.
    // These values can be changed by in-band software so we have to do a full
    // PECI read on every get-property, and can't assume that values will change
    // only when set-property is done.
    mutable unsigned int currentLevel;
    mutable bool bfEnabled;

    /**
     * Enforce common pre-conditions for D-Bus set property handlers.
     */
    void setPropertyCheckOrThrow(SSTInterface& sst)
    {
        if (!sst.supportsControl())
        {
            throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed();
        }
        if (hostState != HostState::postComplete || !sst.ready())
        {
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }
    }

  public:
    CPUConfig(sdbusplus::bus_t& bus_, uint8_t index, CPUModel model,
              unsigned int currentLevel_, bool bfEnabled_) :
        BaseCurrentOperatingConfig(bus_, generatePath(index).c_str(),
                                   action::defer_emit),
        bus(bus_), peciAddress(index + MIN_CLIENT_ADDR),
        path(generatePath(index)), cpuModel(model), currentLevel(currentLevel_),
        bfEnabled(bfEnabled_)
    {}

    //
    // D-Bus Property Overrides
    //

    sdbusplus::message::object_path appliedConfig() const override
    {
        DEBUG_PRINT << "Reading AppliedConfig\n";
        if (hostState != HostState::off)
        {
            // Otherwise, try to read current state
            auto sst = getInstance(peciAddress, cpuModel, dontWake);
            if (!sst || !sst->ready())
            {
                std::cerr << __func__
                          << ": Failed to get SST provider instance\n";
            }
            else
            {
                try
                {
                    currentLevel = sst->currentLevel();
                }
                catch (const PECIError& error)
                {
                    std::cerr << "Failed to get SST-PP level: " << error.what()
                              << "\n";
                }
            }
        }
        return generateConfigPath(currentLevel);
    }

    bool baseSpeedPriorityEnabled() const override
    {
        DEBUG_PRINT << "Reading BaseSpeedPriorityEnabled\n";
        if (hostState != HostState::off)
        {
            auto sst = getInstance(peciAddress, cpuModel, dontWake);
            if (!sst || !sst->ready())
            {
                std::cerr << __func__
                          << ": Failed to get SST provider instance\n";
            }
            else
            {
                try
                {
                    bfEnabled = sst->bfEnabled(currentLevel);
                }
                catch (const PECIError& error)
                {
                    std::cerr << "Failed to get SST-BF status: " << error.what()
                              << "\n";
                }
            }
        }
        return bfEnabled;
    }

    sdbusplus::message::object_path
        appliedConfig(sdbusplus::message::object_path value) override
    {
        DEBUG_PRINT << "Writing AppliedConfig\n";
        const OperatingConfig* newConfig = nullptr;
        for (const auto& config : availConfigs)
        {
            if (config->path == value.str)
            {
                newConfig = config.get();
            }
        }

        if (newConfig == nullptr)
        {
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }

        auto sst = getInstance(peciAddress, cpuModel, wakeAllowed);
        if (!sst)
        {
            std::cerr << __func__ << ": Failed to get SST provider instance\n";
            return sdbusplus::message::object_path();
        }
        try
        {
            setPropertyCheckOrThrow(*sst);
            sst->setCurrentLevel(newConfig->level);
            currentLevel = newConfig->level;
        }
        catch (const PECIError& error)
        {
            std::cerr << "Failed to set new SST-PP level: " << error.what()
                      << "\n";
            throw sdbusplus::xyz::openbmc_project::Common::Device::Error::
                WriteFailure();
        }

        // return value not used
        return sdbusplus::message::object_path();
    }

    bool baseSpeedPriorityEnabled(bool /* value */) override
    {
        DEBUG_PRINT << "Writing BaseSpeedPriorityEnabled not allowed\n";
        throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed();
        // return value not used
        return false;
    }

    //
    // Additions
    //

    OperatingConfig& newConfig(unsigned int level)
    {
        availConfigs.emplace_back(std::make_unique<OperatingConfig>(
            bus, level, generateConfigPath(level)));
        return *availConfigs.back();
    }

    std::string generateConfigPath(unsigned int level) const
    {
        return path + "/config" + std::to_string(level);
    }

    /**
     * Emit the interface added signals which were deferred. This is required
     * for ObjectMapper to pick up the objects, if we initially defered the
     * signal emitting.
     */
    void finalize()
    {
        emit_added();
        for (auto& config : availConfigs)
        {
            config->emit_added();
        }
    }

    static std::string generatePath(int index)
    {
        return cpuPath + std::to_string(index);
    }
};

/**
 * Retrieve the SST parameters for a single config and fill the values into the
 * properties on the D-Bus interface.
 *
 * @param[in,out]   sst         Interface to SST backend.
 * @param[in]       level       Config TDP level to retrieve.
 * @param[out]      config      D-Bus interface to update.
 */
static void getSingleConfig(SSTInterface& sst, unsigned int level,
                            OperatingConfig& config)
{
    config.powerLimit(sst.tdp(level));
    DEBUG_PRINT << " TDP = " << config.powerLimit() << '\n';

    config.availableCoreCount(sst.coreCount(level));
    DEBUG_PRINT << " coreCount = " << config.availableCoreCount() << '\n';

    config.baseSpeed(sst.p1Freq(level));
    DEBUG_PRINT << " baseSpeed = " << config.baseSpeed() << '\n';

    config.maxSpeed(sst.p0Freq(level));
    DEBUG_PRINT << " maxSpeed = " << config.maxSpeed() << '\n';

    config.maxJunctionTemperature(sst.prochotTemp(level));
    DEBUG_PRINT << " procHot = " << config.maxJunctionTemperature() << '\n';

    // Construct BaseSpeedPrioritySettings
    std::vector<std::tuple<uint32_t, std::vector<uint32_t>>> baseSpeeds;
    if (sst.bfSupported(level))
    {
        std::vector<uint32_t> totalCoreList, loFreqCoreList, hiFreqCoreList;
        totalCoreList = sst.enabledCoreList(level);
        hiFreqCoreList = sst.bfHighPriorityCoreList(level);
        std::set_difference(
            totalCoreList.begin(), totalCoreList.end(), hiFreqCoreList.begin(),
            hiFreqCoreList.end(),
            std::inserter(loFreqCoreList, loFreqCoreList.begin()));

        baseSpeeds = {{sst.bfHighPriorityFreq(level), hiFreqCoreList},
                      {sst.bfLowPriorityFreq(level), loFreqCoreList}};
    }
    config.baseSpeedPrioritySettings(baseSpeeds);

    config.turboProfile(sst.sseTurboProfile(level));
}

/**
 * Retrieve all SST configuration info for all discoverable CPUs, and publish
 * the info on new D-Bus objects on the given bus connection.
 *
 * @param[in,out]   ioc     ASIO context.
 * @param[in,out]   conn    D-Bus ASIO connection.
 *
 * @return  Whether discovery was successfully finished.
 *
 * @throw PECIError     A PECI command failed on a CPU which had previously
 *                      responded to a command.
 */
static bool discoverCPUsAndConfigs(boost::asio::io_context& ioc,
                                   sdbusplus::asio::connection& conn)
{
    // Persistent list - only populated after complete/successful discovery
    static std::vector<std::unique_ptr<CPUConfig>> cpus;
    cpus.clear();

    // Temporary staging list. In case there is any failure, these temporary
    // objects will get dropped to avoid presenting incomplete info until the
    // next discovery attempt.
    std::vector<std::unique_ptr<CPUConfig>> cpuList;

    for (uint8_t i = MIN_CLIENT_ADDR; i <= MAX_CLIENT_ADDR; ++i)
    {
        // Let the event handler run any waiting tasks. If there is a lot of
        // PECI contention, SST discovery could take a long time. This lets us
        // get updates to hostState and handle any D-Bus requests.
        ioc.poll();

        if (hostState == HostState::off)
        {
            return false;
        }

        unsigned int cpuIndex = i - MIN_CLIENT_ADDR;
        DEBUG_PRINT << "Discovering CPU " << cpuIndex << '\n';

        // We could possibly check D-Bus for CPU presence and model, but PECI is
        // 10x faster and so much simpler.
        uint8_t cc, stepping;
        CPUModel cpuModel;
        EPECIStatus status = peci_GetCPUID(i, &cpuModel, &stepping, &cc);
        if (status == PECI_CC_TIMEOUT)
        {
            // Timing out indicates the CPU is present but PCS services not
            // working yet. Try again later.
            throw PECIError("Get CPUID timed out");
        }
        if (status == PECI_CC_CPU_NOT_PRESENT)
        {
            continue;
        }
        if (status != PECI_CC_SUCCESS || cc != PECI_DEV_CC_SUCCESS)
        {
            std::cerr << "GetCPUID returned status " << status
                      << ", cc = " << cc << '\n';
            continue;
        }

        std::unique_ptr<SSTInterface> sst = getInstance(i, cpuModel,
                                                        wakeAllowed);

        if (!sst)
        {
            // No supported backend for this CPU.
            continue;
        }

        if (!sst->ready())
        {
            // Supported CPU but it can't be queried yet. Try again later.
            std::cerr << "sst not ready yet\n";
            return false;
        }

        if (!sst->ppEnabled())
        {
            // Supported CPU but the specific SKU doesn't support SST-PP.
            std::cerr << "CPU doesn't support SST-PP\n";
            continue;
        }

        // Create the per-CPU configuration object
        unsigned int currentLevel = sst->currentLevel();
        cpuList.emplace_back(
            std::make_unique<CPUConfig>(conn, cpuIndex, cpuModel, currentLevel,
                                        sst->bfEnabled(currentLevel)));
        CPUConfig& cpu = *cpuList.back();

        bool foundCurrentLevel = false;

        for (unsigned int level = 0; level <= sst->maxLevel(); ++level)
        {
            DEBUG_PRINT << "checking level " << level << ": ";
            // levels 1 and 2 were legacy/deprecated, originally used for AVX
            // license pre-granting. They may be reused for more levels in
            // future generations. So we need to check for discontinuities.
            if (!sst->levelSupported(level))
            {
                DEBUG_PRINT << "not supported\n";
                continue;
            }

            DEBUG_PRINT << "supported\n";

            getSingleConfig(*sst, level, cpu.newConfig(level));

            if (level == currentLevel)
            {
                foundCurrentLevel = true;
            }
        }

        DEBUG_PRINT << "current level is " << currentLevel << '\n';

        if (!foundCurrentLevel)
        {
            // In case we didn't encounter a PECI error, but also didn't find
            // the config which is supposedly applied, we won't be able to
            // populate the CurrentOperatingConfig so we have to remove this CPU
            // from consideration.
            std::cerr << "CPU " << cpuIndex
                      << " claimed SST support but invalid configs\n";
            cpuList.pop_back();
            continue;
        }
    }

    cpuList.swap(cpus);
    std::for_each(cpus.begin(), cpus.end(), [](auto& cpu) { cpu->finalize(); });
    return true;
}

/**
 * Attempt discovery process, and if it fails, wait for 10 seconds to try again.
 */
static void discoverOrWait()
{
    static boost::asio::steady_timer peciRetryTimer(dbus::getIOContext());
    static int peciErrorCount = 0;
    bool finished = false;

    // This function may be called from hostStateHandler or by retrying itself.
    // In case those overlap, cancel any outstanding retry timer.
    peciRetryTimer.cancel();

    try
    {
        DEBUG_PRINT << "Starting discovery\n";
        finished = discoverCPUsAndConfigs(dbus::getIOContext(),
                                          *dbus::getConnection());
    }
    catch (const PECIError& err)
    {
        std::cerr << "PECI Error: " << err.what() << '\n';

        // In case of repeated failure to finish discovery, turn off this
        // feature altogether. Possible cause is that the CPU model does not
        // actually support the necessary commands.
        if (++peciErrorCount >= 50)
        {
            std::cerr << "Aborting SST discovery\n";
            return;
        }

        std::cerr << "Retrying SST discovery later\n";
    }

    DEBUG_PRINT << "Finished discovery attempt: " << finished << '\n';

    // Retry later if no CPUs were available, or there was a PECI error.
    if (!finished)
    {
        peciRetryTimer.expires_after(std::chrono::seconds(10));
        peciRetryTimer.async_wait([](boost::system::error_code ec) {
            if (ec)
            {
                if (ec != boost::asio::error::operation_aborted)
                {
                    std::cerr << "SST PECI Retry Timer failed: " << ec << '\n';
                }
                return;
            }
            discoverOrWait();
        });
    }
}

static void hostStateHandler(HostState prevState, HostState)
{
    if (prevState == HostState::off)
    {
        // Start or re-start discovery any time the host moves out of the
        // powered off state.
        discoverOrWait();
    }
}

void init()
{
    addHostStateCallback(hostStateHandler);
}

} // namespace sst
} // namespace cpu_info
