/**
 * Copyright © 2020 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 "internal_interface.hpp"

#include <sdbusplus/message.hpp>

namespace phosphor
{
namespace led
{
namespace sysfs
{
namespace interface
{

InternalInterface::InternalInterface(sdbusplus::bus_t& bus, const char* path) :
    bus(bus), serverInterface(bus, path, internalInterface, vtable.data(), this)
{}

void InternalInterface::getLedDescr(const std::string& name, LedDescr& ledDescr)
{
    std::vector<std::string> words;
    boost::split(words, name, boost::is_any_of(":"));
    try
    {
        ledDescr.devicename = words.at(0);
        ledDescr.color = words.at(1);
        ledDescr.function = words.at(2);
    }
    catch (const std::out_of_range& e)
    {
        lg2::warning("LED description {DESC} not well formed, error {ERR}",
                     "DESC", name, "ERR", e.what());
        throw e;
    }
}

std::string InternalInterface::getDbusName(const LedDescr& ledDescr)
{
    std::vector<std::string> words;
    words.emplace_back(ledDescr.devicename);
    if (!ledDescr.function.empty())
    {
        words.emplace_back(ledDescr.function);
    }

    if (!ledDescr.color.empty())
    {
        words.emplace_back(ledDescr.color);
    }

    std::string s = boost::join(words, "_");

    sdbusplus::message::object_path path(s);

    return path.str;
}

void InternalInterface::createLEDPath(const std::string& ledName)
{
    std::string name;
    std::string path = devParent + ledName;

    if (!std::filesystem::exists(fs::path(path)))
    {
        lg2::error("No such directory {PATH}", "PATH", path);
        return;
    }

    // Convert LED name in sysfs into DBus name
    LedDescr ledDescr;
    try
    {
        getLedDescr(ledName, ledDescr);
    }
    catch (...)
    {
        // Ignore the error, for simple LED which was not added in 3-part form.
        // The simple LED can appear with it's plain name
    }
    name = getDbusName(ledDescr);

    lg2::debug("LED {NAME} receives dbus name {DBUSNAME}", "NAME", ledName,
               "DBUSNAME", name);

    // Unique path name representing a single LED.
    sdbusplus::message::object_path objPath = std::string(physParent);
    objPath /= name;

    if (leds.contains(objPath))
    {
        return;
    }

    auto sled = std::make_unique<phosphor::led::SysfsLed>(fs::path(path));

    leds.emplace(objPath, std::make_unique<phosphor::led::Physical>(
                              bus, objPath, std::move(sled), ledDescr.color));
}

void InternalInterface::addLED(const std::string& name)
{
    createLEDPath(name);
}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
void InternalInterface::removeLED(const std::string& name)
{
    lg2::debug("RemoveLED is not configured {NAME}", "NAME", name);
}

int InternalInterface::addLedConfigure(sd_bus_message* msg, void* context,
                                       sd_bus_error* error)
{
    if (msg == nullptr && context == nullptr)
    {
        lg2::error("Unable to configure addLed");
        return -EINVAL;
    }

    try
    {
        auto message = sdbusplus::message_t(msg);
        auto ledName = message.unpack<std::string>();

        auto* self = static_cast<InternalInterface*>(context);
        self->addLED(ledName);

        auto reply = message.new_method_return();
        reply.method_return();
    }
    catch (const sdbusplus::exception_t& e)
    {
        return sd_bus_error_set(error, e.name(), e.description());
    }

    return 1;
}

int InternalInterface::removeLedConfigure(sd_bus_message* msg, void* context,
                                          sd_bus_error* error)
{
    if (msg == nullptr && context == nullptr)
    {
        lg2::error("Unable to configure removeLed");
        return -EINVAL;
    }

    try
    {
        auto message = sdbusplus::message_t(msg);
        auto ledName = message.unpack<std::string>();

        auto* self = static_cast<InternalInterface*>(context);
        self->removeLED(ledName);

        auto reply = message.new_method_return();
        reply.method_return();
    }
    catch (const sdbusplus::exception_t& e)
    {
        return sd_bus_error_set(error, e.name(), e.description());
    }

    return 1;
}

const std::array<sdbusplus::vtable::vtable_t, 4> InternalInterface::vtable = {
    sdbusplus::vtable::start(),
    // AddLed method takes a string parameter and returns void
    sdbusplus::vtable::method("AddLED", "s", "", addLedConfigure),
    // RemoveLed method takes a string parameter and returns void
    sdbusplus::vtable::method("RemoveLED", "s", "", removeLedConfigure),
    sdbusplus::vtable::end()};

} // namespace interface
} // namespace sysfs
} // namespace led
} // namespace phosphor
