// 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 deferred 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
