// 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 <cassert>
#include <filesystem>
#include <fstream>
#include <functional>
#include <iostream>
#include <sstream>
#include <string>

int AcquireBus(sd_bus** ret);

extern SensorSnapshot* g_sensor_snapshot;
extern DBusConnectionSnapshot* g_connection_snapshot;
extern sd_bus* g_bus;
extern SensorDetailView* g_sensor_detail_view;
extern FooterView* g_footer_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(
    sd_bus* bus, 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(
                bus, &m, service.c_str(), obj_path.c_str(),
                "org.freedesktop.DBus.Introspectable", "Introspect");
            if (r < 0)
            {
                continue;
            }
            r = sd_bus_call(bus, m, 0, &err, &reply);
            if (r < 0)
            {
                continue;
            }
            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);
                if (r < 0)
                {
                    continue;
                }
                else
                {
                    XMLNode* t = ParseXML(std::string(s));
                    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(sd_bus* bus, DBusConnectionSnapshot** cxn_snapshot,
                    SensorSnapshot** sensor_snapshot)
{
    // Craete new snapshots
    (*cxn_snapshot) = new DBusConnectionSnapshot();
    (*sensor_snapshot) = new SensorSnapshot(*cxn_snapshot);

    g_footer_view->SetStatusString("1. Listing DBus Names");
    DBusTopUpdateFooterView();
    char** names;
    int r = sd_bus_list_names(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);

    g_footer_view->SetStatusString("2. Getting Creds");
    DBusTopUpdateFooterView();
    size_t N = services.size();
    for (size_t i = 0; i < N; i++)
    {
        if (i == N - 1 || (i % 100) == 99)
        {
            g_footer_view->SetStatusString("2. Getting Creds " +
                                           std::to_string(i + 1) + "/" +
                                           std::to_string(N));
            DBusTopUpdateFooterView();
        }
        const std::string& service = services[i];
        sd_bus_creds* creds = nullptr;
        r = sd_bus_get_name_creds(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)
        {}
        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;
        }
        std::string unit;
        r = sd_bus_creds_get_unit(creds, &u);
        if (r >= 0)
        {
            unit = u;
        }
        (*cxn_snapshot)->AddConnection(service, connection, comm, unit, pid);
    }
    // busctl call xyz.openbmc_project.ObjectMapper /
    // org.freedesktop.DBus.Introspectable Introspect

    g_footer_view->SetStatusString("3. Examine objects in ObjectMapper");
    std::vector<std::string> all_obj_paths = FindAllObjectPathsForService(
        bus, "xyz.openbmc_project.ObjectMapper", nullptr);
    N = all_obj_paths.size();
    sd_bus_error err = SD_BUS_ERROR_NULL;
    sd_bus_message *m, *reply;
    for (size_t i = 0; i < N; i++)
    {
        if (i % 100 == 99 || i == N - 1)
        {
            g_footer_view->SetStatusString(
                "3. Examine objects in ObjectMapper " + std::to_string(i + 1) +
                "/" + std::to_string(N));
            DBusTopUpdateFooterView();
        }

        const std::string& p = all_obj_paths[i];
        if (IsSensorObjectPath(p))
        {
            err = SD_BUS_ERROR_NULL;
            r = sd_bus_message_new_method_call(
                bus, &m, "xyz.openbmc_project.ObjectMapper",
                "/xyz/openbmc_project/object_mapper",
                "xyz.openbmc_project.ObjectMapper", "GetObject");
            if (r < 0)
            {
                continue;
            }
            r = sd_bus_message_append_basic(m, 's', p.c_str());
            if (r < 0)
            {
                continue;
            }
            // empty array
            r = sd_bus_message_open_container(m, 'a', "s");
            if (r < 0)
            {
                continue;
            }
            r = sd_bus_message_close_container(m);
            if (r < 0)
            {
                continue;
            }
            r = sd_bus_call(bus, m, 0, &err, &reply);
            if (r < 0)
            {}
            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)
                {
                    continue;
                }
                while (true)
                {
                    r = sd_bus_message_enter_container(
                        reply, SD_BUS_TYPE_DICT_ENTRY, "sas");
                    if (r < 0)
                    {
                        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)
                        {
                            goto DONE;
                        }
                        r = sd_bus_message_enter_container(reply, 'a', "s");
                        if (r < 0)
                        {
                            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)
                            {}
                            else if (r == 0)
                                break;
                            else
                            {
                                if (!strcmp(interface_map_second,
                                            "xyz.openbmc_project.Sensor.Value"))
                                {
                                    has_value_interface = true;
                                }
                            }
                        }
                        if (has_value_interface)
                        {
                            (*sensor_snapshot)
                                ->SetSensorVisibleFromObjectMapper(
                                    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:
        {}
        }
    }

    g_footer_view->SetStatusString("4. List Associations in ObjectMapper");
    DBusTopUpdateFooterView();
    err = SD_BUS_ERROR_NULL;
    r = sd_bus_message_new_method_call(
        bus, &m, "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths");
    if (r < 0)
    {
        assert(0);
    }
    r = sd_bus_message_append_basic(m, 's', "/");
    if (r < 0)
    {
        assert(0);
    }
    const int zero = 0;
    r = sd_bus_message_append_basic(m, 'i', &zero);
    if (r < 0)
    {
        assert(0);
    }
    r = sd_bus_message_open_container(m, 'a', "s");
    if (r < 0)
    {
        assert(0);
    }
    r = sd_bus_message_append_basic(m, 's', "xyz.openbmc_project.Association");
    if (r < 0)
    {
        assert(0);
    }
    r = sd_bus_message_close_container(m);
    if (r < 0)
    {
        assert(0);
    }
    r = sd_bus_call(bus, m, 0, &err, &reply);
    if (r < 0)
    {
        assert(0);
    }
    const char* sig = sd_bus_message_get_signature(reply, 0);
    if (strcmp(sig, "as"))
    {
        assert(0);
    }
    r = sd_bus_message_enter_container(reply, 'a', "s");
    if (r < 0)
    {
        assert(0);
    }
    std::set<std::string> assoc_paths;
    while (true)
    {
        const char* p;
        r = sd_bus_message_read_basic(reply, 's', &p);
        if (r <= 0)
            break;
        else
        {
            assoc_paths.insert(p);
        }
    }
    r = sd_bus_message_exit_container(reply);
    if (r < 0)
    {
        assert(0);
    }

    size_t idx = 0;
    for (const std::string& assoc_path : assoc_paths)
    {
        if (idx % 100 == 99 || idx == N - 1)
        {
            g_footer_view->SetStatusString(
                "4. List Associations in ObjectMapper " +
                std::to_string(idx + 1) + "/" + std::to_string(N));
            DBusTopUpdateFooterView();
        }
        ++idx;
        err = SD_BUS_ERROR_NULL;
        r = sd_bus_message_new_method_call(
            bus, &m, "xyz.openbmc_project.ObjectMapper", assoc_path.c_str(),
            "org.freedesktop.DBus.Properties", "Get");
        r = sd_bus_message_append_basic(m, 's',
                                        "xyz.openbmc_project.Association");
        if (r < 0)
        {
            assert(0);
        }
        r = sd_bus_message_append_basic(m, 's', "endpoints");
        if (r < 0)
        {
            assert(0);
        }
        r = sd_bus_call(bus, m, 0, &err, &reply);
        if (r < 0)
        {
            // The object may not have any endpoints
            continue;
        }
        const char* sig = sd_bus_message_get_signature(reply, 0);
        if (strcmp(sig, "v"))
        {
            assert(0);
        }
        r = sd_bus_message_enter_container(reply, 'v', "as");
        if (r < 0)
        {
            assert(0);
        }
        r = sd_bus_message_enter_container(reply, 'a', "s");
        if (r < 0)
        {
            assert(0);
        }
        std::set<std::string> entries;
        while (true)
        {
            const char* p;
            r = sd_bus_message_read_basic(reply, 's', &p);
            if (r <= 0)
                break;
            entries.insert(p);
        }
        r = sd_bus_message_exit_container(reply);
        if (r < 0)
        {
            assert(0);
        }
        r = sd_bus_message_exit_container(reply);
        if (r < 0)
        {
            assert(0);
        }

        (*sensor_snapshot)->AddAssociationEndpoints(assoc_path, entries);
    }

    g_footer_view->SetStatusString("5. Find Association Definitions");
    DBusTopUpdateFooterView();

    err = SD_BUS_ERROR_NULL;
    r = sd_bus_message_new_method_call(
        bus, &m, "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTree");
    std::vector<std::pair<std::string, std::string>>
        services_and_objects; // Record the Associations from those pairs
    r = sd_bus_message_append_basic(m, 's', "/");
    if (r < 0)
    {
        assert(0);
    }
    r = sd_bus_message_append_basic(m, 'i', &zero);
    if (r < 0)
    {
        assert(0);
    }
    r = sd_bus_message_open_container(m, 'a', "s");
    if (r < 0)
    {
        assert(0);
    }
    r = sd_bus_message_append_basic(
        m, 's', "xyz.openbmc_project.Association.Definitions");
    if (r < 0)
    {
        assert(0);
    }
    r = sd_bus_message_close_container(m);
    if (r < 0)
    {
        assert(0);
    }
    r = sd_bus_call(bus, m, 0, &err, &reply);
    if (r < 0)
    {
        assert(0);
    }
    sig = sd_bus_message_get_signature(reply, 0);
    if (strcmp(sig, "a{sa{sas}}"))
    {
        assert(0);
    }
    r = sd_bus_message_enter_container(reply, 'a', "{sa{sas}}");
    if (r <= 0)
    {
        assert(0);
    }

    idx = 0;
    N = services_and_objects.size();
    while (true)
    {
        if (idx % 100 == 99 || idx == N - 1)
        {
            g_footer_view->SetStatusString("5. Find Association Definitions " +
                                           std::to_string(idx + 1) + "/" +
                                           std::to_string(N));
            DBusTopUpdateFooterView();
        }
        r = sd_bus_message_enter_container(reply, 'e', "sa{sas}");
        if (r <= 0)
        {
            break;
        }              // e denotes 'dict entry'
        const char* p; // path
        r = sd_bus_message_read_basic(reply, 's', &p);
        if (r <= 0)
            break;
        r = sd_bus_message_enter_container(reply, 'a', "{sas}");
        if (r <= 0)
        {
            assert(0);
        }
        while (true)
        {
            const char* service; // service
            r = sd_bus_message_enter_container(reply, 'e', "sas");
            if (r <= 0)
            {
                break;
            }
            r = sd_bus_message_read_basic(reply, 's', &service);
            if (r < 0)
            {
                assert(0);
            }
            services_and_objects.emplace_back(std::string(service),
                                              std::string(p));
            r = sd_bus_message_enter_container(reply, 'a', "s");
            if (r <= 0)
            {
                assert(0);
            }
            while (true)
            {
                const char* iface;
                r = sd_bus_message_read_basic(reply, 's', &iface);
                if (r <= 0)
                {
                    break;
                }
            }
            r = sd_bus_message_exit_container(reply);
            if (r < 0)
            {
                assert(0);
            } // exit a
            r = sd_bus_message_exit_container(reply);
            if (r < 0)
            {
                assert(0);
            } // exit e
        }
        r = sd_bus_message_exit_container(reply);
        if (r < 0)
        {
            assert(0);
        } // exit a
        r = sd_bus_message_exit_container(reply);
        if (r < 0)
        {
            assert(0);
        } // exit e
    }
    r = sd_bus_message_exit_container(reply);
    if (r < 0)
    {
        assert(0);
    } // exit a

    idx = 0;
    N = services_and_objects.size();
    for (const std::pair<std::string, std::string>& serv_and_obj :
         services_and_objects)
    {
        if (idx % 100 == 99 || idx == N - 1)
        {
            g_footer_view->SetStatusString(
                "6. Find Associations of Endpoints " + std::to_string(idx + 1) +
                "/" + std::to_string(N));
            DBusTopUpdateFooterView();
        }
        ++idx;
        err = SD_BUS_ERROR_NULL;
        r = sd_bus_message_new_method_call(
            bus, &m, serv_and_obj.first.c_str(), serv_and_obj.second.c_str(),
            "org.freedesktop.DBus.Properties", "Get");
        if (r < 0)
        {
            assert(0);
        }
        r = sd_bus_message_append_basic(
            m, 's', "xyz.openbmc_project.Association.Definitions");
        if (r < 0)
        {
            assert(0);
        }
        r = sd_bus_message_append_basic(m, 's', "Associations");
        if (r < 0)
        {
            assert(0);
        }
        r = sd_bus_call(bus, m, 0, &err, &reply);
        if (r <= 0)
        {
            continue;
        }
        sig = sd_bus_message_get_signature(reply, 0);
        if (strcmp(sig, "v"))
        {
            assert(0);
        }
        r = sd_bus_message_enter_container(reply, 'v', "a(sss)");
        if (r <= 0)
        {
            continue;
        }
        r = sd_bus_message_enter_container(reply, 'a', "(sss)");
        if (r <= 0)
        {
            continue;
        }
        while (true)
        {
            r = sd_bus_message_enter_container(reply, 'r', "sss");
            if (r <= 0)
            {
                break;
            } // struct
            const char *forward, *reverse, *endpoint;
            r = sd_bus_message_read_basic(reply, 's', &forward);
            if (r < 0)
            {
                break;
            }
            r = sd_bus_message_read_basic(reply, 's', &reverse);
            if (r < 0)
            {
                assert(0);
            }
            r = sd_bus_message_read_basic(reply, 's', &endpoint);
            if (r < 0)
            {
                assert(0);
            }
            (*sensor_snapshot)
                ->AddAssociationDefinition(
                    serv_and_obj.second, std::string(forward),
                    std::string(reverse), std::string(endpoint));
            r = sd_bus_message_exit_container(reply);
            if (r < 0)
            {
                assert(0);
            } // exit struct
        }
        r = sd_bus_message_exit_container(reply);
        if (r < 0)
        {
            assert(0);
        } // exit a
        r = sd_bus_message_exit_container(reply);
        if (r < 0)
        {
            assert(0);
        } // exit v
    }

    g_footer_view->SetStatusString("7. Check HWMon DBus objects");
    DBusTopUpdateFooterView();
    for (size_t i = 0; i < comms.size(); i++)
    {
        if (i % 100 == 99 || i == N - 1)
        {
            g_footer_view->SetStatusString("7. Check HWMon DBus objects " +
                                           std::to_string(i + 1) + "/" +
                                           std::to_string(N));
            DBusTopUpdateFooterView();
        }
        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(bus, service, nullptr);
            for (const std::string& op : objpaths)
            {
                if (IsSensorObjectPath(op))
                {
                    (*sensor_snapshot)->SetSensorVisibleFromHwmon(service, op);
                }
            }
        }
    }

    g_footer_view->SetStatusString("DBus object scan complete");
    DBusTopUpdateFooterView();
}
} // 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;
    }
}
