/**
 * 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 <iostream>
#include <string>
#include "physical.hpp"
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
