/**
 * Copyright © 2017 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 <phosphor-logging/log.hpp>
#include "monitor.hpp"

namespace phosphor
{
namespace unit
{
namespace failure
{

using namespace phosphor::logging;

constexpr auto FAILED_STATE = "failed";
constexpr auto START_METHOD = "StartUnit";
constexpr auto STOP_METHOD = "StopUnit";

constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
constexpr auto SYSTEMD_PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
constexpr auto SYSTEMD_UNIT_INTERFACE = "org.freedesktop.systemd1.Unit";

void Monitor::analyze()
{
    if (inFailedState(std::move(getSourceUnitPath())))
    {
        runTargetAction();
    }
}

bool Monitor::inFailedState(const std::string&& path)
{
    sdbusplus::message::variant<std::string> property;

    auto method = bus.new_method_call(SYSTEMD_SERVICE, path.c_str(),
                                      SYSTEMD_PROPERTY_INTERFACE, "Get");

    method.append(SYSTEMD_UNIT_INTERFACE, "ActiveState");

    auto reply = bus.call(method);
    if (reply.is_method_error())
    {
        log<level::ERR>("Failed reading ActiveState DBus property",
                        entry("UNIT=%s", source.c_str()));
        // TODO openbmc/openbmc#851 - Once available, throw returned error
        throw std::runtime_error("Failed reading ActiveState DBus property");
    }

    reply.read(property);

    auto value = sdbusplus::message::variant_ns::get<std::string>(property);
    return (value == FAILED_STATE);
}

std::string Monitor::getSourceUnitPath()
{
    sdbusplus::message::object_path path;

    auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
                                      SYSTEMD_INTERFACE, "GetUnit");
    method.append(source);
    auto reply = bus.call(method);

    if (reply.is_method_error())
    {
        log<level::ERR>("Failed GetUnit DBus method call",
                        entry("UNIT=%s", source.c_str()));
        // TODO openbmc/openbmc#851 - Once available, throw returned error
        throw std::runtime_error("Failed GetUnit DBus method call");
    }

    reply.read(path);

    return static_cast<std::string>(path);
}

void Monitor::runTargetAction()
{
    // Start or stop the target unit
    auto methodCall = (action == Action::start) ? START_METHOD : STOP_METHOD;

    log<level::INFO>("The source unit is in failed state, "
                     "running target action",
                     entry("SOURCE=%s", source.c_str()),
                     entry("TARGET=%s", target.c_str()),
                     entry("ACTION=%s", methodCall));

    auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
                                            SYSTEMD_INTERFACE, methodCall);
    method.append(target);
    method.append("replace");

    auto reply = bus.call(method);

    if (reply.is_method_error())
    {
        log<level::ERR>("Failed to run action on the target unit",
                        entry("UNIT=%s", target.c_str()));
        // TODO openbmc/openbmc#851 - Once available, throw returned error
        throw std::runtime_error("Failed to run action on the target unit");
    }
}
}
}
}
