/**
 * Copyright 2017 Google Inc.
 *
 * 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.
 */

#ifdef ENABLE_IPMI_SNOOP
#include "ipmisnoop/ipmisnoop.hpp"
#endif

#include "lpcsnoop/snoop.hpp"

#include <endian.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/epoll.h>
#include <systemd/sd-event.h>
#include <unistd.h>

#include <chrono>
#include <cstdint>
#include <exception>
#include <functional>
#include <iostream>
#include <optional>
#include <sdeventplus/event.hpp>
#include <sdeventplus/source/event.hpp>
#include <sdeventplus/source/io.hpp>
#include <sdeventplus/source/signal.hpp>
#include <sdeventplus/source/time.hpp>
#include <sdeventplus/utility/sdbus.hpp>
#include <span>
#include <stdplus/signal.hpp>
#include <thread>

#ifdef ENABLE_IPMI_SNOOP
#include <xyz/openbmc_project/State/Boot/Raw/server.hpp>
#endif

static size_t codeSize = 1; /* Size of each POST code in bytes */
const char* defaultHostInstances = "0";
static bool verbose = false;
#ifdef ENABLE_IPMI_SNOOP
const uint8_t minPositionVal = 0;
const uint8_t maxPositionVal = 5;
#endif

#ifdef ENABLE_IPMI_SNOOP
std::vector<std::unique_ptr<IpmiPostReporter>> reporters;
#endif

#ifdef ENABLE_IPMI_SNOOP
void IpmiPostReporter::getSelectorPositionSignal(sdbusplus::bus_t& bus)
{
    size_t posVal = 0;

    matchSignal = std::make_unique<sdbusplus::bus::match_t>(
        bus,
        sdbusplus::bus::match::rules::propertiesChanged(selectorObject,
                                                        selectorIface),
        [&](sdbusplus::message_t& msg) {
            std::string objectName;
            std::map<std::string, Selector::PropertiesVariant> msgData;
            msg.read(objectName, msgData);

            auto valPropMap = msgData.find("Position");
            {
                if (valPropMap == msgData.end())
                {
                    std::cerr << "Position property not found " << std::endl;
                    return;
                }

                posVal = std::get<size_t>(valPropMap->second);

                if (posVal > minPositionVal && posVal < maxPositionVal)
                {
                    std::tuple<uint64_t, secondary_post_code_t> postcodes =
                        reporters[posVal - 1]->value();
                    uint64_t postcode = std::get<uint64_t>(postcodes);

                    // write postcode into seven segment display
                    if (postCodeDisplay(postcode) < 0)
                    {
                        fprintf(stderr, "Error in display the postcode\n");
                    }
                }
            }
        });
}
#endif

static void usage(const char* name)
{
    fprintf(stderr,
            "Usage: %s [-d <DEVICE>]\n"
            "  -b, --bytes <SIZE>     set POST code length to <SIZE> bytes. "
            "Default is %zu\n"
            "  -d, --device <DEVICE>  use <DEVICE> file.\n"
            "  -h, --host <host instances>  . Default is '%s'\n"
            "  -v, --verbose  Prints verbose information while running\n\n",
            name, codeSize, defaultHostInstances);
}

/**
 * Call once for each POST code received. If the number of POST codes exceeds
 * the configured rate limit, this function will disable the snoop device IO
 * source until the end of the 1 second interval, then re-enable it.
 *
 * @return Whether the rate limit is exceeded.
 */
bool rateLimit(PostReporter& reporter, sdeventplus::source::IO& ioSource)
{
    if (reporter.rateLimit == 0)
    {
        // Rate limiting is disabled.
        return false;
    }

    using Clock = sdeventplus::Clock<sdeventplus::ClockId::Monotonic>;

    static constexpr std::chrono::seconds rateLimitInterval(1);
    static unsigned int rateLimitCount = 0;
    static Clock::time_point rateLimitEndTime;

    const sdeventplus::Event& event = ioSource.get_event();

    if (rateLimitCount == 0)
    {
        // Initialize the end time when we start a new interval
        rateLimitEndTime = Clock(event).now() + rateLimitInterval;
    }

    if (++rateLimitCount < reporter.rateLimit)
    {
        return false;
    }

    rateLimitCount = 0;

    if (rateLimitEndTime < Clock(event).now())
    {
        return false;
    }

    if (verbose)
    {
        fprintf(stderr, "Hit POST code rate limit - disabling temporarily\n");
    }

    ioSource.set_enabled(sdeventplus::source::Enabled::Off);
    sdeventplus::source::Time<sdeventplus::ClockId::Monotonic>(
        event, rateLimitEndTime, std::chrono::milliseconds(100),
        [&ioSource](auto&, auto) {
            if (verbose)
            {
                fprintf(stderr, "Reenabling POST code handler\n");
            }
            ioSource.set_enabled(sdeventplus::source::Enabled::On);
        })
        .set_floating(true);
    return true;
}

/*
 * Callback handling IO event from the POST code fd. i.e. there is new
 * POST code available to read.
 */
void PostCodeEventHandler(PostReporter* reporter, sdeventplus::source::IO& s,
                          int postFd, uint32_t)
{
    uint64_t code = 0;
    ssize_t readb;

    while ((readb = read(postFd, &code, codeSize)) > 0)
    {
        code = le64toh(code);
        if (verbose)
        {
            fprintf(stderr, "Code: 0x%" PRIx64 "\n", code);
        }
        // HACK: Always send property changed signal even for the same code
        // since we are single threaded, external users will never see the
        // first value.
        reporter->value(std::make_tuple(~code, secondary_post_code_t{}), true);
        reporter->value(std::make_tuple(code, secondary_post_code_t{}));

        // read depends on old data being cleared since it doens't always read
        // the full code size
        code = 0;

        if (rateLimit(*reporter, s))
        {
            return;
        }
    }

    if (readb < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
    {
        return;
    }

    /* Read failure. */
    if (readb == 0)
    {
        fprintf(stderr, "Unexpected EOF reading postcode\n");
    }
    else
    {
        fprintf(stderr, "Failed to read postcode: %s\n", strerror(errno));
    }
    s.get_event().exit(1);
}

#ifdef ENABLE_IPMI_SNOOP
// handle muti-host D-bus
int postCodeIpmiHandler(const std::string& snoopObject,
                        const std::string& snoopDbus, sdbusplus::bus_t& bus,
                        std::span<std::string> host)
{
    int ret = 0;

    try
    {
        for (size_t iteration = 0; iteration < host.size(); iteration++)
        {
            std::string objPathInst = snoopObject + host[iteration];

            sdbusplus::server::manager_t m{bus, objPathInst.c_str()};

            /* Create a monitor object and let it do all the rest */
            reporters.emplace_back(
                std::make_unique<IpmiPostReporter>(bus, objPathInst.c_str()));

            reporters[iteration]->emit_object_added();
        }

        bus.request_name(snoopDbus.c_str());

        /* sevenSegmentLedEnabled flag is unset when GPIO pins are not there 7
        seg display for fewer platforms. So, the code for postcode dispay and
        Get Selector position can be skipped in those platforms.
        */
        if (sevenSegmentLedEnabled)
        {
            reporters[0]->getSelectorPositionSignal(bus);
        }
        else
        {
            reporters.clear();
        }
    }
    catch (const std::exception& e)
    {
        fprintf(stderr, "%s\n", e.what());
    }

    // Configure seven segment dsiplay connected to GPIOs as output
    ret = configGPIODirOutput();
    if (ret < 0)
    {
        fprintf(stderr, "Failed find the gpio line. Cannot display postcodes "
                        "in seven segment display..\n");
    }

    while (true)
    {
        bus.process_discard();
        bus.wait();
    }
    exit(EXIT_SUCCESS);
}
#endif

/*
 * TODO(venture): this only listens one of the possible snoop ports, but
 * doesn't share the namespace.
 *
 * This polls() the lpc snoop character device and it owns the dbus object
 * whose value is the latest port 80h value.
 */
int main(int argc, char* argv[])
{

#ifndef ENABLE_IPMI_SNOOP
    int postFd = -1;
#endif
    unsigned int rateLimit = 0;

    int opt;

#ifdef ENABLE_IPMI_SNOOP
    std::vector<std::string> host;
#endif
    /*
     * These string constants are only used in this method within this object
     * and this object is the only object feeding into the final binary.
     *
     * If however, another object is added to this binary it would be proper
     * to move these declarations to be global and extern to the other object.
     */

    // clang-format off
    static const struct option long_options[] = {
        #ifdef ENABLE_IPMI_SNOOP
        {"host", optional_argument, NULL, 'h'},
        #endif
        {"bytes",  required_argument, NULL, 'b'},
        #ifndef ENABLE_IPMI_SNOOP
        {"device", optional_argument, NULL, 'd'},
        #endif
        {"rate-limit", optional_argument, NULL, 'r'},
        {"verbose", no_argument, NULL, 'v'},
        {0, 0, 0, 0}
    };
    // clang-format on

    while ((opt = getopt_long(argc, argv, "h:b:d:r:v", long_options, NULL)) !=
           -1)
    {
        switch (opt)
        {
            case 0:
                break;
#ifdef ENABLE_IPMI_SNOOP
            case 'h': {
                std::string_view instances = optarg;
                size_t pos = 0;

                while ((pos = instances.find(" ")) != std::string::npos)
                {
                    host.emplace_back(instances.substr(0, pos));
                    instances.remove_prefix(pos + 1);
                }
                host.emplace_back(instances);
                break;
            }
#endif
            case 'b': {
                codeSize = atoi(optarg);

                if (codeSize < 1 || codeSize > 8)
                {
                    fprintf(stderr,
                            "Invalid POST code size '%s'. Must be "
                            "an integer from 1 to 8.\n",
                            optarg);
                    exit(EXIT_FAILURE);
                }
                break;
            }
#ifndef ENABLE_IPMI_SNOOP
            case 'd':

                postFd = open(optarg, O_NONBLOCK);
                if (postFd < 0)
                {
                    fprintf(stderr, "Unable to open: %s\n", optarg);
                    return -1;
                }
                break;
#endif
            case 'r': {
                int argVal = -1;
                try
                {
                    argVal = std::stoi(optarg);
                }
                catch (...)
                {
                }

                if (argVal < 1)
                {
                    fprintf(stderr, "Invalid rate limit '%s'. Must be >= 1.\n",
                            optarg);
                    return EXIT_FAILURE;
                }

                rateLimit = static_cast<unsigned int>(argVal);
                fprintf(stderr, "Rate limiting to %d POST codes per second.\n",
                        argVal);
                break;
            }
            case 'v':
                verbose = true;
                break;
            default:
                usage(argv[0]);
                return EXIT_FAILURE;
        }
    }

    auto bus = sdbusplus::bus::new_default();

#ifdef ENABLE_IPMI_SNOOP
    std::cout << "Verbose = " << verbose << std::endl;
    int ret = postCodeIpmiHandler(ipmiSnoopObject, snoopDbus, bus, host);
    if (ret < 0)
    {
        fprintf(stderr, "Error in postCodeIpmiHandler\n");
        return ret;
    }
    return 0;
#endif

#ifndef ENABLE_IPMI_SNOOP

    bool deferSignals = true;

    // Add systemd object manager.
    sdbusplus::server::manager_t snoopdManager(bus, snoopObject);

    PostReporter reporter(bus, snoopObject, deferSignals);
    reporter.emit_object_added();
    bus.request_name(snoopDbus);

    // Create sdevent and add IO source
    try
    {
        sdeventplus::Event event = sdeventplus::Event::get_default();
        std::optional<sdeventplus::source::IO> reporterSource;
        if (postFd > 0)
        {
            reporter.rateLimit = rateLimit;
            reporterSource.emplace(
                event, postFd, EPOLLIN,
                std::bind_front(PostCodeEventHandler, &reporter));
        }
        // Enable bus to handle incoming IO and bus events
        auto intCb = [](sdeventplus::source::Signal& source,
                        const struct signalfd_siginfo*) {
            source.get_event().exit(0);
        };
        stdplus::signal::block(SIGINT);
        sdeventplus::source::Signal(event, SIGINT, intCb).set_floating(true);
        stdplus::signal::block(SIGTERM);
        sdeventplus::source::Signal(event, SIGTERM, std::move(intCb))
            .set_floating(true);
        return sdeventplus::utility::loopWithBus(event, bus);
    }
    catch (const std::exception& e)
    {
        fprintf(stderr, "%s\n", e.what());
    }

    if (postFd > -1)
    {
        close(postFd);
    }

    return 0;
#endif
}
