/**
 * Copyright © 2016 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 "physical.hpp"

#include <iostream>
#include <string>
namespace phosphor
{
namespace led
{

/** @brief Populates key parameters */
void Physical::setInitialState()
{
    // Control files in /sys/class/leds/<led-name>
    brightCtrl = path + BRIGHTNESS;
    blinkCtrl = path + BLINKCTRL;

    delayOnCtrl = path + DELAYON;
    delayOffCtrl = path + DELAYOFF;

    // 1. read /sys/class/leds/name/trigger
    // 2. If its 'timer', then its blinking.
    //    2.1: On blink, use delay_on and delay_off into dutyOn
    // 3. If its 'none', then read brightness. 255 means, its ON, else OFF.

    auto trigger = read<std::string>(blinkCtrl);
    if (trigger == "timer")
    {
        // LED is blinking. Get the delay_on and delay_off and compute
        // DutyCycle. sfsfs values are in strings. Need to convert 'em over to
        // integer.
        auto delayOn = std::stoi(read<std::string>(delayOnCtrl));
        auto delayOff = std::stoi(read<std::string>(delayOffCtrl));

        // Calculate frequency and then percentage ON
        frequency = delayOn + delayOff;
        auto factor = frequency / 100;
        auto dutyOn = delayOn / factor;

        // Update.
        this->dutyOn(dutyOn);
    }
    else
    {
        // This is hardcoded for now. This will be changed to this->frequency()
        // when frequency is implemented.
        // TODO
        frequency = 1000;

        // LED is either ON or OFF
        auto brightness = read<std::string>(brightCtrl);
        if (brightness == std::string(ASSERT))
        {
            // LED is in Solid ON
            sdbusplus::xyz::openbmc_project::Led::server ::Physical::state(
                Action::On);
        }
        else
        {
            // LED is in OFF state
            sdbusplus::xyz::openbmc_project::Led::server ::Physical::state(
                Action::Off);
        }
    }
    return;
}

/** @brief Overloaded State Property Setter function */
auto Physical::state(Action value) -> Action
{
    // Obtain current operation
    auto current =
        sdbusplus::xyz::openbmc_project::Led::server ::Physical::state();

    // Update requested operation into base class
    auto requested =
        sdbusplus::xyz::openbmc_project::Led::server ::Physical::state(value);

    // Apply the action.
    driveLED(current, requested);

    return value;
}

/** @brief apply action on the LED */
void Physical::driveLED(Action current, Action request)
{
    if (current == request)
    {
        // Best we can do here is ignore.
        return;
    }

    // Transition TO Blinking state
    if (request == Action::Blink)
    {
        return blinkOperation();
    }

    // Transition TO Stable states.
    if (request == Action::On || request == Action::Off)
    {
        return stableStateOperation(request);
    }
    return;
}

/** @brief Either TurnON -or- TurnOFF */
void Physical::stableStateOperation(Action action)
{
    auto value = (action == Action::On) ? ASSERT : DEASSERT;

    // Write "none" to trigger to clear any previous action
    write(blinkCtrl, "none");

    // And write the current command
    write(brightCtrl, value);
    return;
}

/** @brief BLINK the LED */
void Physical::blinkOperation()
{
    // Get the latest dutyOn that the user requested
    auto dutyOn = this->dutyOn();

    // Write "timer" to "trigger" file
    write(blinkCtrl, "timer");

    // Write DutyON. Value in percentage 1_millisecond.
    // so 50% input becomes 500. Driver wants string input
    auto percentage = frequency / 100;
    write(delayOnCtrl, std::to_string(dutyOn * percentage));

    // Write DutyOFF. Value in milli seconds so 50% input becomes 500.
    write(delayOffCtrl, std::to_string((100 - dutyOn) * percentage));
    return;
}

} // namespace led
} // namespace phosphor
