// Copyright 2021 Google LLC
//
// 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 "analyzer.hpp"

#include "histogram.hpp"
#include "main.hpp"
#include "sensorhelper.hpp"
#include "views.hpp"
#include "xmlparse.hpp"

#include <unistd.h>

#include <atomic>
#include <filesystem>
#include <fstream>
#include <functional>
#include <iostream>
#include <sstream>
#include <string>

extern SensorSnapshot* g_sensor_snapshot;
extern DBusConnectionSnapshot* g_connection_snapshot;
extern sd_bus* g_bus;
extern SensorDetailView* g_sensor_detail_view;

static std::unordered_map<uint64_t, uint64_t>
    in_flight_methodcalls; // serial => microseconds
uint64_t Microseconds()
{
    long us;  // usec
    time_t s; // Seconds
    struct timespec spec;
    clock_gettime(CLOCK_REALTIME, &spec);
    s = spec.tv_sec;
    us = round(spec.tv_nsec / 1000); // Convert nanoseconds to milliseconds
    if (us > 999999)
    {
        s++;
        us = 0;
    }
    return s * 1000000 + us;
}

int g_update_interval_millises = 2000;
int GetSummaryIntervalInMillises()
{
    return g_update_interval_millises;
}

bool DBusTopSortFieldIsNumeric(DBusTopSortField field)
{
    switch (field)
    {
        case kSender:
        case kDestination:
        case kInterface:
        case kPath:
        case kMember:
        case kSenderCMD:
            return false;
        case kSenderPID:
        case kMsgPerSec:
        case kAverageLatency:
            return true;
    }
    return false;
}

namespace dbus_top_analyzer
{
DBusTopStatistics g_dbus_statistics;
Histogram<float> g_mc_time_histogram;
std::unordered_map<uint32_t, uint64_t> in_flight_methodcalls;
std::atomic<bool> g_program_done = false;
std::chrono::time_point<std::chrono::steady_clock> g_last_update;
DBusTopStatisticsCallback g_callback;
void SetDBusTopStatisticsCallback(DBusTopStatisticsCallback cb)
{
    g_callback = cb;
}

int UserInputThread()
{
    return 0;
}

std::string g_dbus_top_conn = " ";
void SetDBusTopConnectionForMonitoring(const std::string& conn)
{
    g_dbus_top_conn = conn;
}

// Performs one step of analysis
void Process()
{
    std::chrono::time_point<std::chrono::steady_clock> t =
        std::chrono::steady_clock::now();
    std::chrono::time_point<std::chrono::steady_clock> next_update =
        g_last_update + std::chrono::milliseconds(g_update_interval_millises);
    if (t >= next_update)
    {
        float seconds_since_last_sample =
            std::chrono::duration_cast<std::chrono::microseconds>(t -
                                                                  g_last_update)
                .count() /
            1000000.0f;
        g_dbus_statistics.seconds_since_last_sample_ =
            seconds_since_last_sample;
        // Update snapshot
        if (g_callback)
        {
            g_callback(&g_dbus_statistics, &g_mc_time_histogram);
        }
        g_dbus_statistics.Reset();
        g_last_update = t;
    }
}

void Finish()
{
    g_program_done = true;
}

std::vector<std::string> FindAllObjectPathsForService(
    const std::string& service,
    std::function<void(const std::string&, const std::vector<std::string>&)>
        on_interface_cb)
{
    sd_bus_error err = SD_BUS_ERROR_NULL;
    sd_bus_message *m, *reply;
    std::vector<std::string> paths; // Current iteration
    std::vector<std::string>
        all_obj_paths; // All object paths under the supervision of ObjectMapper
    paths.push_back("/");
    // busctl call xyz.openbmc_project.ObjectMapper        /
    // org.freedesktop.DBus.Introspectable        Introspect
    while (!paths.empty())
    {
        // printf("%d paths to explore, total %d paths so far\n",
        // int(paths.size()), int(all_obj_paths.size()));
        std::vector<std::string> new_paths;
        for (const std::string& obj_path : paths)
        {
            all_obj_paths.push_back(obj_path);
            int r = sd_bus_message_new_method_call(
                g_bus, &m, service.c_str(), obj_path.c_str(),
                "org.freedesktop.DBus.Introspectable", "Introspect");
            if (r < 0)
            {
                printf("Oh! Cannot create new method call. r=%d, strerror=%s\n",
                       r, strerror(-r));
                continue;
            }
            r = sd_bus_call(g_bus, m, 0, &err, &reply);
            if (r < 0)
            {
                printf("Could not execute method call, r=%d, strerror=%s\n", r,
                       strerror(-r));
            }
            const char* sig = sd_bus_message_get_signature(reply, 0);
            if (!strcmp(sig, "s"))
            {
                const char* s;
                int r = sd_bus_message_read(reply, "s", &s);
                std::string s1(s);
                if (r < 0)
                {
                    printf("Could not read string payload, r=%d, strerror=%s\n",
                           r, strerror(-r));
                }
                else
                {
                    XMLNode* t = ParseXML(s1);
                    std::vector<std::string> ch = t->GetChildNodeNames();
                    if (on_interface_cb != nullptr)
                    {
                        on_interface_cb(obj_path, t->GetInterfaceNames());
                    }
                    DeleteTree(t);
                    for (const std::string& cn : ch)
                    {
                        std::string ch_path = obj_path;
                        if (obj_path.back() == '/')
                        {}
                        else
                            ch_path.push_back('/');
                        ch_path += cn;
                        new_paths.push_back(ch_path);
                    }
                }
            }
        }
        paths = new_paths;
    }
    return all_obj_paths;
}

void ListAllSensors()
{
    g_connection_snapshot = new DBusConnectionSnapshot();
    printf("1. Getting names\n");
    char** names;
    int r = sd_bus_list_names(g_bus, &names, nullptr);
    std::vector<std::string> services;
    std::vector<int> pids;
    std::vector<std::string> comms;
    for (char** ptr = names; ptr && *ptr; ++ptr)
    {
        services.push_back(*ptr);
        free(*ptr);
    }
    free(names);
    printf("2. Getting creds of each name\n");
    for (int i = 0; i < static_cast<int>(services.size()); i++)
    {
        const std::string& service = services[i];
        sd_bus_creds* creds = nullptr;
        r = sd_bus_get_name_creds(g_bus, services[i].c_str(),
                                  SD_BUS_CREDS_AUGMENT | SD_BUS_CREDS_EUID |
                                      SD_BUS_CREDS_PID | SD_BUS_CREDS_COMM |
                                      SD_BUS_CREDS_UNIQUE_NAME |
                                      SD_BUS_CREDS_UNIT | SD_BUS_CREDS_SESSION |
                                      SD_BUS_CREDS_DESCRIPTION,
                                  &creds);
        // PID
        int pid = INVALID;
        if (r < 0)
        {
            printf("Oh! Cannot get creds for %s\n", services[i].c_str());
        }
        else
        {
            r = sd_bus_creds_get_pid(creds, &pid);
        }
        pids.push_back(pid);
        // comm
        std::string comm;
        if (pid != INVALID)
        {
            std::ifstream ifs("/proc/" + std::to_string(pid) + "/cmdline");
            std::string line;
            std::getline(ifs, line);
            for (char c : line)
            {
                if (c < 32 || c >= 127)
                    c = ' ';
                comm.push_back(c);
            }
        }
        comms.push_back(comm);
        // unique name, also known as "Connection"
        std::string connection;
        const char* u;
        r = sd_bus_creds_get_unique_name(creds, &u);
        if (r >= 0)
        {
            connection = u;
        }
        else
        {
            printf("Oh! Could not get unique name for %s\n", service.c_str());
        }
        std::string unit;
        r = sd_bus_creds_get_unit(creds, &u);
        if (r >= 0)
        {
            unit = u;
        }
        else
        {
            printf("Oh! Could not get unit name for %s\n", unit.c_str());
        }
        printf("AddConnection    %s    %s    %s    %s    %d\n", service.c_str(),
               connection.c_str(), comm.c_str(), unit.c_str(), pid);
        g_connection_snapshot->AddConnection(service, connection, comm, unit,
                                             pid);
    }
    printf("There are %d DBus names.\n", int(services.size()));
    for (int i = 0; i < int(services.size()); i++)
    {
        printf("    %d: %s [%s]\n", i, services[i].c_str(), comms[i].c_str());
    }
    g_sensor_snapshot = new SensorSnapshot(g_connection_snapshot);
    // busctl call xyz.openbmc_project.ObjectMapper /
    // org.freedesktop.DBus.Introspectable Introspect
    printf("3. See which sensors are visible from Object Mapper\n");
    printf("3.1. Introspect Object Mapper for object paths\n");
    std::vector<std::string> all_obj_paths = FindAllObjectPathsForService(
        "xyz.openbmc_project.ObjectMapper", nullptr);
    sd_bus_error err = SD_BUS_ERROR_NULL;
    sd_bus_message *m, *reply;
    printf("%d paths found while introspecting ObjectMapper.\n",
           int(all_obj_paths.size()));
    printf("3.2. Call ObjectMapper's GetObject method against the sensor "
           "object paths that represent sensors\n");
    for (const std::string& p : all_obj_paths)
    {
        if (IsSensorObjectPath(p))
        {
            err = SD_BUS_ERROR_NULL;
            r = sd_bus_message_new_method_call(
                g_bus, &m, "xyz.openbmc_project.ObjectMapper",
                "/xyz/openbmc_project/object_mapper",
                "xyz.openbmc_project.ObjectMapper", "GetObject");
            if (r < 0)
            {
                printf("Cannot create new method call. r=%d, strerror=%s\n", r,
                       strerror(-r));
                continue;
            }
            r = sd_bus_message_append_basic(m, 's', p.c_str());
            if (r < 0)
            {
                printf("Could not append a string parameter to m\n");
                continue;
            }
            // empty array
            r = sd_bus_message_open_container(m, 'a', "s");
            if (r < 0)
            {
                printf("Could not open a container for m\n");
                continue;
            }
            r = sd_bus_message_close_container(m);
            if (r < 0)
            {
                printf("Could not close container for m\n");
                continue;
            }
            r = sd_bus_call(g_bus, m, 0, &err, &reply);
            if (r < 0)
            {
                printf("Error performing dbus method call\n");
            }
            const char* sig = sd_bus_message_get_signature(reply, 0);
            if (!strcmp(sig, "a{sas}"))
            {
                r = sd_bus_message_enter_container(reply, 'a', "{sas}");
                if (r < 0)
                {
                    printf("Could not enter the level 0 array container\n");
                    continue;
                }
                while (true)
                {
                    r = sd_bus_message_enter_container(
                        reply, SD_BUS_TYPE_DICT_ENTRY, "sas");
                    if (r < 0)
                    {
                        // printf("Could not enter the level 1 dict
                        // container\n");
                        goto DONE;
                    }
                    else if (r == 0)
                    {}
                    else
                    {
                        // The following 2 correspond to `interface_map` in
                        // phosphor-mapper
                        const char* interface_map_first;
                        r = sd_bus_message_read_basic(reply, 's',
                                                      &interface_map_first);
                        if (r < 0)
                        {
                            printf("Could not read interface_map_first\n");
                            goto DONE;
                        }
                        r = sd_bus_message_enter_container(reply, 'a', "s");
                        if (r < 0)
                        {
                            printf("Could not enter the level 2 array "
                                   "container\n");
                            goto DONE;
                        }
                        bool has_value_interface = false;
                        while (true)
                        {
                            const char* interface_map_second;
                            r = sd_bus_message_read_basic(
                                reply, 's', &interface_map_second);
                            if (r < 0)
                            {
                                printf("Could not read interface_map_second\n");
                            }
                            else if (r == 0)
                                break;
                            else
                            {
                                // printf("    %s\n", interface_map_second);
                                if (!strcmp(interface_map_second,
                                            "xyz.openbmc_project.Sensor.Value"))
                                {
                                    has_value_interface = true;
                                }
                            }
                        }
                        if (has_value_interface)
                        {
                            g_sensor_snapshot->SerSensorVisibleFromObjectMapper(
                                std::string(interface_map_first), p);
                        }
                        r = sd_bus_message_exit_container(reply);
                    }
                    r = sd_bus_message_exit_container(reply);
                }
                r = sd_bus_message_exit_container(reply);
            }
        DONE:
        {}
        }
    }
    printf("4. Check Hwmon's DBus objects\n");
    for (int i = 0; i < int(comms.size()); i++)
    {
        const std::string& comm = comms[i];
        const std::string& service = services[i];
        if (comm.find("phosphor-hwmon-readd") != std::string::npos &&
            !IsUniqueName(service))
        {
            // printf("Should introspect %s\n", service.c_str());
            std::vector<std::string> objpaths =
                FindAllObjectPathsForService(service, nullptr);
            for (const std::string& op : objpaths)
            {
                if (IsSensorObjectPath(op))
                {
                    g_sensor_snapshot->SetSensorVisibleFromHwmon(service, op);
                }
            }
        }
    }
    // Call `ipmitool sdr list` and see which sensors exist.
    printf("5. Checking ipmitool SDR List\n");
    std::string out;
    bool skip_sdr_list = false;
    if (getenv("SKIP"))
    {
        skip_sdr_list = true;
    }
    if (!skip_sdr_list)
    {
        constexpr int MAX_BUFFER = 255;
        char buffer[MAX_BUFFER];
        FILE* stream = popen("ipmitool sdr list", "r");
        while (fgets(buffer, MAX_BUFFER, stream) != NULL)
        {
            out.append(buffer);
        }
        pclose(stream);
    }
    std::stringstream ss(out);
    while (true)
    {
        std::string sensor_id, reading, status;
        std::getline(ss, sensor_id, '|');
        std::getline(ss, reading, '|');
        std::getline(ss, status);
        // printf("%s %s %s\n", sensor_id.c_str(), reading.c_str(),
        // status.c_str());
        if (sensor_id.size() > 0 && reading.size() > 0 && status.size() > 0)
        {
            g_sensor_snapshot->SetSensorVisibleFromIpmitoolSdr(Trim(sensor_id));
        }
        else
            break;
    }
    printf("=== Sensors snapshot summary: ===\n");
    g_sensor_snapshot->PrintSummary();
}
} // namespace dbus_top_analyzer

void DBusTopStatistics::OnNewDBusMessage(const char* sender,
                                         const char* destination,
                                         const char* interface,
                                         const char* path, const char* member,
                                         const char type, sd_bus_message* m)
{
    num_messages_++;
    std::vector<std::string> keys;

    std::string sender_orig = CheckAndFixNullString(sender);
    std::string dest_orig = CheckAndFixNullString(destination);
    // For method return messages, we actually want to show the sender
    // and destination of the original method call, so we swap the
    // sender and destination
    if (type == 2)
    { // DBUS_MESSAGE_TYPE_METHOD_METHOD_RETURN
        std::swap(sender_orig, dest_orig);
    }

    // Special case: when PID == 1 (init), the DBus unit would be systemd.
    // It seems it was not possible to obtain the connection name of systemd
    // so we manually set it here.
    const int sender_orig_pid =
        g_connection_snapshot->GetConnectionPIDFromNameOrUniqueName(
            sender_orig);

    if (sender_orig_pid == 1)
    {
        sender_orig = "systemd";
    }
    const int dest_orig_pid =
        g_connection_snapshot->GetConnectionPIDFromNameOrUniqueName(dest_orig);
    if (dest_orig_pid == 1)
    {
        dest_orig = "systemd";
    }

    for (DBusTopSortField field : fields_)
    {
        switch (field)
        {
            case kSender:
                keys.push_back(sender_orig);
                break;
            case kDestination:
                keys.push_back(dest_orig);
                break;
            case kInterface:
                keys.push_back(CheckAndFixNullString(interface));
                break;
            case kPath:
                keys.push_back(CheckAndFixNullString(path));
                break;
            case kMember:
                keys.push_back(CheckAndFixNullString(member));
                break;
            case kSenderPID:
            {
                if (sender_orig_pid != INVALID)
                {
                    keys.push_back(std::to_string(sender_orig_pid));
                }
                else
                {
                    keys.push_back("(unknown)");
                }
                break;
            }
            case kSenderCMD:
            {
                keys.push_back(
                    g_connection_snapshot->GetConnectionCMDFromNameOrUniqueName(
                        sender_orig));
                break;
            }
            case kMsgPerSec:
            case kAverageLatency:
                break; // Don't populate "keys" using these 2 fields
        }
    }
    // keys = combination of fields of user's choice

    if (stats_.count(keys) == 0)
    {
        stats_[keys] = DBusTopComputedMetrics();
    }
    // Need to update msg/s regardless
    switch (type)
    {
        case 1: // DBUS_MESSAGE_TYPE_METHOD_CALL
            stats_[keys].num_method_calls++;
            break;
        case 2: // DBUS_MESSAGE_TYPE_METHOD_METHOD_RETURN
            stats_[keys].num_method_returns++;
            break;
        case 3: // DBUS_MESSAGE_TYPE_ERROR
            stats_[keys].num_errors++;
            break;
        case 4: // DBUS_MESSAGE_TYPE_SIGNAL
            stats_[keys].num_signals++;
            break;
    }
    // Update global latency histogram
    // For method call latency
    if (type == 1) // DBUS_MESSAGE_TYPE_METHOD_CALL
    {
        uint64_t serial; // serial == cookie
        sd_bus_message_get_cookie(m, &serial);
        in_flight_methodcalls[serial] = Microseconds();
    }
    else if (type == 2) // DBUS_MESSAGE_TYPE_MEHOTD_RETURN
    {
        uint64_t reply_serial = 0; // serial == cookie
        sd_bus_message_get_reply_cookie(m, &reply_serial);
        if (in_flight_methodcalls.count(reply_serial) > 0)
        {
            float dt_usec =
                Microseconds() - in_flight_methodcalls[reply_serial];
            in_flight_methodcalls.erase(reply_serial);
            dbus_top_analyzer::g_mc_time_histogram.AddSample(dt_usec);

            // Add method call count and total latency to the corresponding key
            stats_[keys].total_latency_usec += dt_usec;
        }
    }
    // For meaning of type see here
    // https://dbus.freedesktop.org/doc/api/html/group__DBusProtocol.html#ga4a9012edd7f22342f845e98150aeb858
    switch (type)
    {
        case 1:
            num_mc_++;
            break;
        case 2:
            num_mr_++;
            break;
        case 3:
            num_error_++;
            break;
        case 4:
            num_sig_++;
            break;
    }
}
