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

#include <iostream>
#include <systemd/sd-journal.h>
#include <sstream>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/log.hpp>
#include "elog-gen.hpp"

using namespace phosphor;
using namespace logging;

// 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 main()
{
    // 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::TestErrorOne>(
                example::xyz::openbmc_project::Example::TestErrorOne::
                    ERRNUM(number),
                example::xyz::openbmc_project::Example::TestErrorOne::
                    FILE_PATH(test_string),
                example::xyz::openbmc_project::Example::TestErrorOne::
                    FILE_NAME("elog_test_3.txt"),
                example::xyz::openbmc_project::Example::TestErrorTwo::
                    DEV_ADDR(0xDEADDEAD),
                example::xyz::openbmc_project::Example::TestErrorTwo::
                    DEV_ID(100),
                example::xyz::openbmc_project::Example::TestErrorTwo::
                    DEV_NAME("test case 3"));
    }
    catch (elogException<example::xyz::openbmc_project::Example::TestErrorOne>& e)
    {
        std::cout << "elog exception caught: " << e.what() << std::endl;
    }

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

    // 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 (elogExceptionBase& 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;
}


