/*
// 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)
    {
        // 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;
}
