/**
 * 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/log.hpp>
#include <xyz/openbmc_project/Control/Host/server.hpp>

#include <chrono>
namespace phosphor
{
namespace ipmi
{

using namespace phosphor::logging;
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)
    {
        log<level::ERR>("Error in call to control host Execute",
                        entry("ERROR=%s", e.what()));
        // 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);

    log<level::DEBUG>("Host control signal values",
                      entry("COMMAND=%s", cmdCompleted.c_str()),
                      entry("STATUS=%s", cmdStatus.c_str()));

    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)
        {
            log<level::ERR>("Failure to start Host shutdown wait timer",
                            entry("ERRNO=0x%X", -r));
        }
        else
        {
            log<level::INFO>(
                "Timer started waiting for host to shutdown",
                entry("TIMEOUT_IN_MSEC=%llu",
                      (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
        log<level::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)
        {
            log<level::ERR>("Failure to STOP the timer",
                            entry("ERRNO=0x%X", -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
