// 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;
    }
}
