/*
// 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 <PwmSensor.hpp>
#include <Utils.hpp>
#include <sdbusplus/asio/object_server.hpp>

#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>

static constexpr double sysPwmMax = 255.0;
static constexpr double psuPwmMax = 100.0;
static constexpr double defaultPwm = 30.0;
static constexpr double targetIfaceMax = sysPwmMax;

PwmSensor::PwmSensor(const std::string& name, const std::string& sysPath,
                     std::shared_ptr<sdbusplus::asio::connection>& conn,
                     sdbusplus::asio::object_server& objectServer,
                     const std::string& sensorConfiguration,
                     const std::string& sensorType, bool isValueMutable) :
    sysPath(sysPath),
    objectServer(objectServer), name(name)
{
    // add interface under sensor and Control.FanPwm as Control is used
    // in obmc project, also add sensor so it can be viewed as a sensor
    sensorInterface = objectServer.add_interface(
        "/xyz/openbmc_project/sensors/fan_pwm/" + name,
        "xyz.openbmc_project.Sensor.Value");
    uint32_t pwmValue = getValue(false);
    if (sensorType == "PSU")
    {
        pwmMax = psuPwmMax;
    }
    else
    {
        pwmMax = sysPwmMax;
    }

    if (pwmValue == 0U)
    {
        // default pwm to non 0
        pwmValue = static_cast<uint32_t>(pwmMax * (defaultPwm / 100.0));
        setValue(pwmValue);
    }
    double fValue = 100.0 * (static_cast<double>(pwmValue) / pwmMax);
    sensorInterface->register_property(
        "Value", fValue,
        [this](const double& req, double& resp) {
        if (!std::isfinite(req))
        {
            // Reject attempted change, if to NaN or other non-numeric
            return -1;
        }
        if (req > 100.0 || req < 0.0)
        {
            // TODO(): It does not seem desirable to halt daemon here,
            // probably should just reject the change, continue running?
            throw std::runtime_error("Value out of range");
            return -1;
        }

        double reqValue = (req / 100.0) * pwmMax;
        double respValue = (resp / 100.0) * pwmMax;
        auto reqInt = static_cast<uint32_t>(std::round(reqValue));
        auto respInt = static_cast<uint32_t>(std::round(respValue));
        // Avoid floating-point equality, compare as integers
        if (reqInt == respInt)
        {
            return 1;
        }
        setValue(reqInt);
        resp = req;

        controlInterface->signal_property("Target");

        return 1;
        },
        [this](double& curVal) {
        double currScaled = (curVal / 100.0) * pwmMax;
        auto currInt = static_cast<uint32_t>(std::round(currScaled));
        auto getInt = getValue();
        // Avoid floating-point equality, compare as integers
        if (currInt != getInt)
        {
            double getScaled = 100.0 * (static_cast<double>(getInt) / pwmMax);
            curVal = getScaled;
            controlInterface->signal_property("Target");
            sensorInterface->signal_property("Value");
        }
        return curVal;
    });
    // pwm sensor interface is in percent
    sensorInterface->register_property("MaxValue", static_cast<int64_t>(100));
    sensorInterface->register_property("MinValue", static_cast<int64_t>(0));
    sensorInterface->register_property("Unit", sensor_paths::unitPercent);

    controlInterface = objectServer.add_interface(
        "/xyz/openbmc_project/control/fanpwm/" + name,
        "xyz.openbmc_project.Control.FanPwm");
    controlInterface->register_property(
        "Target", static_cast<uint64_t>(pwmValue),
        [this](const uint64_t& req, uint64_t& resp) {
        if (req > static_cast<uint64_t>(targetIfaceMax))
        {
            throw std::runtime_error("Value out of range");
            return -1;
        }
        if (req == resp)
        {
            return 1;
        }
        auto scaledValue = static_cast<double>(req) / targetIfaceMax;
        auto roundValue = std::round(scaledValue * pwmMax);
        setValue(static_cast<uint32_t>(roundValue));
        resp = req;

        sensorInterface->signal_property("Value");

        return 1;
        },
        [this](uint64_t& curVal) {
        auto getInt = getValue();
        auto scaledValue = static_cast<double>(getInt) / pwmMax;
        auto roundValue = std::round(scaledValue * targetIfaceMax);
        auto value = static_cast<uint64_t>(roundValue);
        if (curVal != value)
        {
            curVal = value;
            controlInterface->signal_property("Target");
            sensorInterface->signal_property("Value");
        }
        return curVal;
    });

    sensorInterface->initialize();
    controlInterface->initialize();

    if (isValueMutable)
    {
        valueMutabilityInterface =
            std::make_shared<sdbusplus::asio::dbus_interface>(
                conn, sensorInterface->get_object_path(),
                valueMutabilityInterfaceName);
        valueMutabilityInterface->register_property("Mutable", true);
        if (!valueMutabilityInterface->initialize())
        {
            std::cerr
                << "error initializing sensor value mutability interface\n";
            valueMutabilityInterface = nullptr;
        }
    }

    association = objectServer.add_interface(
        "/xyz/openbmc_project/sensors/fan_pwm/" + name, association::interface);

    // PowerSupply sensors should be associated with chassis board path
    // and inventory along with psu object.
    if (sensorType == "PSU")
    {
        createInventoryAssoc(conn, association, sensorConfiguration);
    }
    else
    {
        createAssociation(association, sensorConfiguration);
    }
}
PwmSensor::~PwmSensor()
{
    objectServer.remove_interface(sensorInterface);
    objectServer.remove_interface(controlInterface);
    objectServer.remove_interface(association);
}

void PwmSensor::setValue(uint32_t value)
{
    std::ofstream ref(sysPath);
    if (!ref.good())
    {
        throw std::runtime_error("Bad Write File");
    }
    ref << value;
}

// on success returns pwm, on failure throws except on initialization, where it
// prints an error and returns 0
uint32_t PwmSensor::getValue(bool errThrow)
{
    std::ifstream ref(sysPath);
    if (!ref.good())
    {
        return -1;
    }
    std::string line;
    if (!std::getline(ref, line))
    {
        return -1;
    }
    try
    {
        uint32_t value = std::stoi(line);
        return value;
    }
    catch (const std::invalid_argument&)
    {
        std::cerr << "Error reading pwm at " << sysPath << "\n";
        // throw if not initial read to be caught by dbus bindings
        if (errThrow)
        {
            throw std::runtime_error("Bad Read");
        }
    }
    return 0;
}
