/*
// Copyright (c) 2018 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 "utils.hpp"

void checkAndThrowInternalFailure(boost::system::error_code& ec,
                                  const std::string& msg)
{
    if (ec)
    {
        std::string msgToLog = ec.message() + (msg.empty() ? "" : " - " + msg);
        lg2::error("Check and throw internal failure: {MSG}", "MSG", msgToLog);
        phosphor::logging::elog<
            sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();
    }
    return;
}

void systemdDaemonReload(
    const std::shared_ptr<sdbusplus::asio::connection>& conn,
    boost::asio::yield_context yield)
{
    boost::system::error_code ec;
    conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath, sysdMgrIntf,
                              sysdReloadMethod);
    checkAndThrowInternalFailure(ec, "daemon-reload operation failed");
    return;
}

static inline uint32_t getJobId(const std::string& path)
{
    auto pos = path.rfind("/");
    if (pos == std::string::npos)
    {
        lg2::error("Unable to get job id from  {PATH}.", "PATH", path);
        phosphor::logging::elog<
            sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();
    }
    return static_cast<uint32_t>(std::stoul(path.substr(pos + 1)));
}

void systemdUnitAction(const std::shared_ptr<sdbusplus::asio::connection>& conn,
                       boost::asio::yield_context yield,
                       const std::string& unitName,
                       const std::string& actionMethod)
{
    boost::system::error_code ec;
    auto jobPath = conn->yield_method_call<sdbusplus::message::object_path>(
        yield, ec, sysdService, sysdObjPath, sysdMgrIntf, actionMethod,
        unitName, sysdReplaceMode);
    checkAndThrowInternalFailure(ec,
                                 "Systemd operation failed, " + actionMethod);
    // Query the job till it doesn't exist anymore.
    // this way we guarantee that queued job id is done.
    // this is needed to make sure dependency list on units are
    // properly handled.
    while (true)
    {
        ec.clear();
        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
                                  sysdMgrIntf, sysdGetJobMethod,
                                  getJobId(jobPath.str));
        if (ec)
        {
            if (ec.value() == boost::system::errc::no_such_file_or_directory)
            {
                // Queued job is done, return now
                return;
            }
            lg2::error("Systemd operation failed for job query: {EC}", "EC",
                       ec.value());
            phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
                                        Error::InternalFailure>();
        }
        boost::asio::steady_timer sleepTimer(conn->get_io_context());
        sleepTimer.expires_after(std::chrono::milliseconds(20));
        ec.clear();
        sleepTimer.async_wait(yield[ec]);
        checkAndThrowInternalFailure(ec, "Systemd operation timer error");
    }
    return;
}

void systemdUnitFilesStateChange(
    const std::shared_ptr<sdbusplus::asio::connection>& conn,
    boost::asio::yield_context yield, const std::vector<std::string>& unitFiles,
    const std::string& unitState, bool maskedState, bool enabledState)
{
    boost::system::error_code ec;

    if (unitState == stateMasked && !maskedState)
    {
        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
                                  sysdMgrIntf, "UnmaskUnitFiles", unitFiles,
                                  false);
        checkAndThrowInternalFailure(ec, "Systemd UnmaskUnitFiles() failed.");
    }
    else if (unitState != stateMasked && maskedState)
    {
        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
                                  sysdMgrIntf, "MaskUnitFiles", unitFiles,
                                  false, false);
        checkAndThrowInternalFailure(ec, "Systemd MaskUnitFiles() failed.");
    }
    ec.clear();
    if (unitState != stateEnabled && enabledState)
    {
        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
                                  sysdMgrIntf, "EnableUnitFiles", unitFiles,
                                  false, false);
        checkAndThrowInternalFailure(ec, "Systemd EnableUnitFiles() failed.");
    }
    else if (unitState != stateDisabled && !enabledState)
    {
        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
                                  sysdMgrIntf, "DisableUnitFiles", unitFiles,
                                  false);
        checkAndThrowInternalFailure(ec, "Systemd DisableUnitFiles() failed.");
    }
    return;
}
