/**
 * 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 "config.h"

#include "pgood_monitor.hpp"

#include "elog-errors.hpp"
#include "utility.hpp"

#include <org/open_power/Witherspoon/Fault/error.hpp>
#include <phosphor-logging/lg2.hpp>

namespace phosphor
{
namespace power
{

constexpr auto POWER_OBJ_PATH = "/org/openbmc/control/power0";
constexpr auto POWER_INTERFACE = "org.openbmc.control.Power";

using namespace sdbusplus::org::open_power::Witherspoon::Fault::Error;

bool PGOODMonitor::pgoodPending()
{
    bool pending = false;
    int32_t state = 0;
    int32_t pgood = 0;

    auto service = util::getService(POWER_OBJ_PATH, POWER_INTERFACE, bus);

    util::getProperty<int32_t>(POWER_INTERFACE, "pgood", POWER_OBJ_PATH,
                               service, bus, pgood);

    // When state = 1, system was switched on
    util::getProperty<int32_t>(POWER_INTERFACE, "state", POWER_OBJ_PATH,
                               service, bus, state);

    // On but no PGOOD
    if (state && !pgood)
    {
        pending = true;
    }

    return pending;
}

void PGOODMonitor::analyze()
{
    // Timer callback.
    // The timer expired before it was stopped.
    // If PGOOD is still pending (it should be),
    // then there is a real failure.

    if (pgoodPending())
    {
#ifdef DEVICE_ACCESS
        device->onFailure();
#endif
        phosphor::logging::report<PowerOnFailure>();
    }

    // The pgood-wait service (with a longer timeout)
    // will handle powering off the system.
    timer.get_event().exit(EXIT_SUCCESS);
}

void PGOODMonitor::propertyChanged()
{
    // Multiple properties could have changed here.
    // Keep things simple and just recheck the important ones.
    if (!pgoodPending())
    {
        // PGOOD is on, or system is off, so we are done.
        timer.get_event().exit(EXIT_SUCCESS);
    }
}

void PGOODMonitor::startListening()
{
    match = std::make_unique<sdbusplus::bus::match_t>(
        bus,
        sdbusplus::bus::match::rules::propertiesChanged(POWER_OBJ_PATH,
                                                        POWER_INTERFACE),
        [this](auto&) { this->propertyChanged(); });
}

int PGOODMonitor::run()
{
    try
    {
        startListening();

        // If PGOOD came up before we got here, we're done.
        // Otherwise if PGOOD doesn't get asserted before
        // the timer expires, it's a failure.
        if (!pgoodPending())
        {
            return EXIT_SUCCESS;
        }

        return timer.get_event().loop();
    }
    catch (const std::exception& e)
    {
        lg2::error("Unexpected failure prevented PGOOD checking: {ERROR}",
                   "ERROR", e);
    }

    // Letting the service fail won't help anything, so don't do it.
    return EXIT_SUCCESS;
}

} // namespace power
} // namespace phosphor
