/**
 * Copyright © 2016 IBM 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 "config.h"

#include "softoff.hpp"

#include <ipmid/utils.hpp>
#include <phosphor-logging/lg2.hpp>
#include <xyz/openbmc_project/Control/Host/server.hpp>

#include <chrono>
namespace phosphor
{
namespace ipmi
{

using namespace sdbusplus::server::xyz::openbmc_project::control;

void SoftPowerOff::sendHostShutDownCmd()
{
    auto ctrlHostPath = std::string{CONTROL_HOST_OBJ_MGR} + '/' + HOST_NAME +
                        '0';
    auto host = ::ipmi::getService(this->bus, CONTROL_HOST_BUSNAME,
                                   ctrlHostPath.c_str());

    auto method = bus.new_method_call(host.c_str(), ctrlHostPath.c_str(),
                                      CONTROL_HOST_BUSNAME, "Execute");

    method.append(convertForMessage(Host::Command::SoftOff).c_str());
    try
    {
        auto reply = bus.call(method);
    }
    catch (const std::exception& e)
    {
        lg2::error("Error in call to control host Execute: {ERROR}", "ERROR",
                   e);
        // TODO openbmc/openbmc#851 - Once available, throw returned error
        throw std::runtime_error("Error in call to control host Execute");
    }
}

// Function called on host control signals
void SoftPowerOff::hostControlEvent(sdbusplus::message_t& msg)
{
    std::string cmdCompleted{};
    std::string cmdStatus{};

    msg.read(cmdCompleted, cmdStatus);

    lg2::debug(
        "Host control signal values, command: {COMMAND}, status:{STATUS}",
        "COMMAND", cmdCompleted, "STATUS", cmdStatus);

    if (Host::convertResultFromString(cmdStatus) == Host::Result::Success)
    {
        // Set our internal property indicating we got host attention
        sdbusplus::server::xyz::openbmc_project::ipmi::internal::SoftPowerOff::
            responseReceived(HostResponse::SoftOffReceived);

        // Start timer for host shutdown
        using namespace std::chrono;
        auto time = duration_cast<microseconds>(
            seconds(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS));
        auto r = startTimer(time);
        if (r < 0)
        {
            lg2::error(
                "Failure to start Host shutdown wait timer, ERRNO: {ERRNO}",
                "ERRNO", lg2::hex, -r);
        }
        else
        {
            lg2::info("Timer started waiting for host to shutdown, "
                      "TIMEOUT_IN_MSEC: {TIMEOUT_IN_MSEC}",
                      "TIMEOUT_IN_MSEC",
                      (duration_cast<milliseconds>(
                           seconds(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS)))
                          .count());
        }
    }
    else
    {
        // An error on the initial attention is not considered an error, just
        // exit normally and allow remaining shutdown targets to run
        lg2::info("Timeout on host attention, continue with power down");
        completed = true;
    }
    return;
}

// Starts a timer
int SoftPowerOff::startTimer(const std::chrono::microseconds& usec)
{
    return timer.start(usec);
}

// Host Response handler
auto SoftPowerOff::responseReceived(HostResponse response) -> HostResponse
{
    using namespace std::chrono;

    if (response == HostResponse::HostShutdown)
    {
        // Disable the timer since Host has quiesced and we are
        // done with soft power off part
        auto r = timer.stop();
        if (r < 0)
        {
            lg2::error("Failure to STOP the timer, ERRNO: {ERRNO}", "ERRNO",
                       lg2::hex, -r);
        }

        // This marks the completion of soft power off sequence.
        completed = true;
    }

    return sdbusplus::server::xyz::openbmc_project::ipmi::internal::
        SoftPowerOff::responseReceived(response);
}

} // namespace ipmi
} // namespace phosphor
