// A basic unit test that runs on a BMC (qemu or hardware)

#include <getopt.h>
#include <systemd/sd-journal.h>

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/exception.hpp>

#include <cstring>
#include <iostream>
#include <sstream>

using namespace phosphor;
using namespace logging;

const char* usage = "Usage: logging-test [OPTION]          \n\n\
Options:                                                     \n\
[NONE]                          Default test case.           \n\
-h, --help                      Display this usage text.     \n\
-c, --commit <string>           Commit desired error.      \n\n\
Valid errors to commit:                                      \n\
AutoTestSimple, AutoTestCreateAndCommit\n";

// validate the journal metadata equals the input value
int validate_journal(const char* i_entry, const char* i_value)
{
    sd_journal* journal;
    const void* data;
    size_t l;
    int rc;
    bool validated = false;

    rc = sd_journal_open(&journal, SD_JOURNAL_LOCAL_ONLY);
    if (rc < 0)
    {
        std::cerr << "Failed to open journal: " << strerror(-rc) << "\n";
        return 1;
    }
    rc = sd_journal_query_unique(journal, i_entry);
    if (rc < 0)
    {
        std::cerr << "Failed to query journal: " << strerror(-rc) << "\n";
        return 1;
    }
    SD_JOURNAL_FOREACH_UNIQUE(journal, data, l)
    {
        std::string journ_entry((const char*)data);
        std::cout << journ_entry << "\n";
        if (journ_entry.find(i_value) != std::string::npos)
        {
            std::cout << "We found it!\n";
            validated = true;
            break;
        }
    }

    sd_journal_close(journal);

    rc = (validated) ? 0 : 1;
    if (rc)
    {
        std::cerr << "Failed to find " << i_entry << " with value " << i_value
                  << " in journal!"
                  << "\n";
    }

    return rc;
}

int elog_test()
{
    // TEST 1 - Basic log
    log<level::DEBUG>("Basic phosphor logging test");

    // TEST 2 - Log with metadata field
    const char* file_name = "phosphor_logging_test.txt";
    int number = 0xFEFE;
    log<level::DEBUG>(
        "phosphor logging test with attribute",
        entry("FILE_NAME_WITH_NUM_TEST=%s_%x", file_name, number));

    // Now read back and verify our data made it into the journal
    int rc = validate_journal("FILE_NAME_WITH_NUM_TEST",
                              "phosphor_logging_test.txt_fefe");
    if (rc)
        return (rc);

    // TEST 3 - Create error log with 2 meta data fields (rvalue and lvalue)
    number = 0x1234;
    const char* test_string = "/tmp/test_string/";
    try
    {
        elog<example::xyz::openbmc_project::example::elog::TestErrorOne>(
            example::xyz::openbmc_project::example::elog::TestErrorOne::ERRNUM(
                number),
            example::xyz::openbmc_project::example::elog::TestErrorOne::
                FILE_PATH(test_string),
            example::xyz::openbmc_project::example::elog::TestErrorOne::
                FILE_NAME("elog_test_3.txt"),
            example::xyz::openbmc_project::example::elog::TestErrorTwo::
                DEV_ADDR(0xDEADDEAD),
            example::xyz::openbmc_project::example::elog::TestErrorTwo::DEV_ID(
                100),
            example::xyz::openbmc_project::example::elog::TestErrorTwo::
                DEV_NAME("test case 3"));
    }
    catch (const example::xyz::openbmc_project::example::elog::TestErrorOne& e)
    {
        std::cout << "elog exception caught: " << e.what() << std::endl;
    }

    // Reduce our error namespaces
    using namespace example::xyz::openbmc_project::example::elog;

    // Now read back and verify our data made it into the journal
    std::stringstream stream;
    stream << std::hex << number;
    rc = validate_journal(TestErrorOne::ERRNUM::str_short,
                          std::string(stream.str()).c_str());
    if (rc)
        return (rc);

    rc = validate_journal(TestErrorOne::FILE_PATH::str_short, test_string);
    if (rc)
        return (rc);

    rc =
        validate_journal(TestErrorOne::FILE_NAME::str_short, "elog_test_3.txt");
    if (rc)
        return (rc);

    rc = validate_journal(TestErrorTwo::DEV_ADDR::str_short, "0xDEADDEAD");
    if (rc)
        return (rc);

    rc = validate_journal(TestErrorTwo::DEV_ID::str_short, "100");
    if (rc)
        return (rc);

    rc = validate_journal(TestErrorTwo::DEV_NAME::str_short, "test case 3");
    if (rc)
        return (rc);

    // TEST 4 - Create error log with previous entry use
    number = 0x9876;
    try
    {
        elog<TestErrorOne>(
            TestErrorOne::ERRNUM(number), prev_entry<TestErrorOne::FILE_PATH>(),
            TestErrorOne::FILE_NAME("elog_test_4.txt"),
            TestErrorTwo::DEV_ADDR(0xDEADDEAD), TestErrorTwo::DEV_ID(100),
            TestErrorTwo::DEV_NAME("test case 4"));
    }
    catch (const sdbusplus::exception_t& e)
    {
        std::cout << "elog exception caught: " << e.what() << std::endl;
    }

    // Now read back and verify our data made it into the journal
    stream.str("");
    stream << std::hex << number;
    rc = validate_journal(TestErrorOne::ERRNUM::str_short,
                          std::string(stream.str()).c_str());
    if (rc)
        return (rc);

    // This should just be equal to what we put in test 3
    rc = validate_journal(TestErrorOne::FILE_PATH::str_short, test_string);
    if (rc)
        return (rc);

    rc =
        validate_journal(TestErrorOne::FILE_NAME::str_short, "elog_test_4.txt");
    if (rc)
        return (rc);

    rc = validate_journal(TestErrorTwo::DEV_ADDR::str_short, "0xDEADDEAD");
    if (rc)
        return (rc);

    rc = validate_journal(TestErrorTwo::DEV_ID::str_short, "100");
    if (rc)
        return (rc);

    rc = validate_journal(TestErrorTwo::DEV_NAME::str_short, "test case 4");
    if (rc)
        return (rc);

    // Compile fail tests

    // Simple test to prove we fail to compile due to missing param
    // elog<TestErrorOne>(TestErrorOne::ERRNUM(1),
    //                   TestErrorOne::FILE_PATH("test"));

    // Simple test to prove we fail to compile due to invalid param
    // elog<TestErrorOne>(TestErrorOne::ERRNUM(1),
    //                   TestErrorOne::FILE_PATH("test"),
    //                   TestErrorOne::FILE_NAME(1));

    return 0;
}

void commitError(const char* text)
{
    if (std::strcmp(text, "AutoTestSimple") == 0)
    {
        try
        {
            elog<example::xyz::openbmc_project::example::elog::AutoTestSimple>(
                example::xyz::openbmc_project::example::elog::AutoTestSimple::
                    STRING("FOO"));
        }
        catch (
            const example::xyz::openbmc_project::example::elog::AutoTestSimple&
                e)
        {
            std::cout << "elog exception caught: " << e.what() << std::endl;
            commit(e.name());
        }
    }
    else if (std::strcmp(text, "AutoTestCreateAndCommit") == 0)
    {
        report<example::xyz::openbmc_project::example::elog::AutoTestSimple>(
            example::xyz::openbmc_project::example::elog::AutoTestSimple::
                STRING("FOO"));
    }

    return;
}

int main(int argc, char* argv[])
{
    int arg;

    if (argc == 1)
        return elog_test();

    static struct option long_options[] = {
        {"help", no_argument, 0, 'h'},
        {"commit", required_argument, 0, 'c'},
        {0, 0, 0, 0}};
    int option_index = 0;

    while ((arg = getopt_long(argc, argv, "hc:", long_options,
                              &option_index)) != -1)
    {
        switch (arg)
        {
            case 'c':
                commitError(optarg);
                return 0;
            case 'h':
            case '?':
                std::cerr << usage;
                return 1;
        }
    }

    return 0;
}
