// 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 "views.hpp"
#include "bargraph.hpp"
#include "histogram.hpp"
#include "menu.hpp"
#include <string.h>
#include <algorithm>

extern SensorSnapshot* g_sensor_snapshot;
extern BarGraph<float>* g_bargraph;
extern DBusTopStatistics* g_dbus_statistics;
extern Histogram<float>* g_histogram;
extern DBusTopWindow* g_current_active_view;
extern const std::string FieldNames[];
extern const int FieldPreferredWidths[];

namespace dbus_top_analyzer
{
    extern DBusTopStatistics g_dbus_statistics;
}

// Linear interpolation
float Lerp(float a, float b, float t)
{
    return a + t * (b - a);
}

// Linear map
float Map(float value, float start1, float stop1, float start2, float stop2,
          bool within_bounds)
{
    float t = (value - start1) / (stop1 - start1);
    float ret = Lerp(start2, stop2, t);
    if (within_bounds)
    {
        if (ret < start2)
            ret = start2;
        if (ret > stop2)
            ret = stop2;
    }
    return ret;
}

template <typename T>
void HistoryBarGraph(WINDOW* win, const Rect& rect, BarGraph<T>* bargraph)
{
    const int RIGHT_MARGIN = 5;
    const int x0 = rect.x, y0 = 2;
    const int w = rect.w - 2 - RIGHT_MARGIN;
    const int h = rect.h - 3; // height of content
    wattrset(win, 0);
    wattron(win, A_BOLD | A_UNDERLINE);
    mvwaddstr(win, 1, x0, "History     (Total msg/s)");
    wattrset(win, 0);
    // 1. Obtain data, determine Y range
    std::vector<float> data = bargraph->GetLastNValues(w - RIGHT_MARGIN - 1);
    float ymax = -1e20, ymin = 1e20;
    if (data.empty())
    {
        data.push_back(0);
        ymin = 0;
        ymax = 10;
    }
    else
    {
        for (const float x : data)
        {
            ymax = std::max(ymax, x);
            ymin = std::min(ymin, x);
        }
    }
    // Fix edge case for both == 0
    float diff = ymax - ymin;
    if (diff < 0)
    {
        diff = -diff;
    }
    const float EPS = 1e-4;
    if (diff < EPS)
    {
        ymax += 10;
        ymin -= 10;
    }
    // Choose a suitable round-up unit to snap the grid labels to
    int snap = 1;
    if (ymax < 100)
    {
        snap = 10;
    }
    else if (ymax < 10000)
    {
        snap = 100;
    }
    else
    {
        snap = 1000;
    }
    const float eps = snap / 100.0f;
    int label_ymax =
        (static_cast<int>((ymax - eps) / snap) + 1) * snap; // round up
    int label_ymin = static_cast<int>(ymin / snap) * snap;  // round down
    float y_per_row = (label_ymax - label_ymin) * 1.0f / (h - 1);
    int actual_ymax = label_ymax + static_cast<int>(y_per_row / 2);
    int actual_ymin = label_ymin - static_cast<int>(y_per_row / 2);
    // 2. Print Y axis ticks
    for (int i = 0; i < h; i++)
    {
        char buf[10];
        snprintf(
            buf, sizeof(buf), "%-6d",
            static_cast<int>(Lerp(label_ymax, label_ymin, i * 1.0f / (h - 1))));
        mvwaddstr(win, i + y0, x0 + w - RIGHT_MARGIN + 1, buf);
        mvwaddch(win, i + y0, x0, '-');
        mvwaddch(win, i + y0, x0 + w - RIGHT_MARGIN, '-');
    }
    // 3. Go through the historical data and draw on the canvas
    for (int i = 0;
         i < std::min(static_cast<int>(data.size()), w - RIGHT_MARGIN - 1); i++)
    {
        float value = data[i];
        // antialiasing: todo for now
        // float value1 = value; // value1 is 1 column to the right
        // if (i > 0) value1 = data[i-1];
        int x = x0 + w - i - RIGHT_MARGIN - 1;
        float t = Map(value, actual_ymin, actual_ymax, 0, h, true);
        int row = static_cast<int>(t);
        float remaining = t - row;
        char ch; // Last filling character
        if (remaining >= 0.66f)
        {
            ch = ':';
        }
        else if (remaining >= 0.33f)
        {
            ch = '.';
        }
        else
        {
            ch = ' ';
        }
        int y = y0 + h - row - 1;
        mvwaddch(win, y, x, ch);
        for (int j = 0; j < row; j++)
        {
            mvwaddch(win, y + j + 1, x, ':');
        }
    }
}

template <typename T>
void DrawHistogram(WINDOW* win, const Rect& rect, Histogram<T>* histogram)
{
    // const int MARGIN = 7;  // 5 digits margin
    const int LEFT_MARGIN = 7;
    // const int max_bucket_h = histogram->MaxBucketHeight();
    const int H_PAD = 0, V_PAD = 1;
    // x0, x1, y0 and y1 are the bounding box of the contents to be printed
    const int x0 = rect.x + H_PAD;
    const int x1 = rect.x + rect.w - H_PAD;
    const int y0 = rect.y + V_PAD;
    const int y1 = rect.y + rect.h - 1 - V_PAD;
    // Title
    wattron(win, A_BOLD | A_UNDERLINE);
    mvwaddstr(win, y0, x0, "Method Call Time (us) Histogram");
    wattrset(win, 0);
    // x2 is the beginning X of the histogram itself (not containing the margin)
    const int x2 = x0 + LEFT_MARGIN;
    if (histogram->Empty())
    {
        mvwaddstr(win, (y1 + y0) / 2, (x0 + x1) / 2, "(Empty)");
        return;
    }
    histogram->SetBucketCount(x1 - x2 + 1);
    histogram->ComputeHistogram();
    // Draw X axis labels
    char buf[22];
    snprintf(buf, sizeof(buf), "%.2f",
             static_cast<float>(histogram->LowPercentile()));
    mvwaddstr(win, y1, x0 + LEFT_MARGIN, buf);
    snprintf(buf, sizeof(buf), "%.2f",
             static_cast<float>(histogram->HighPercentile()));
    mvwaddstr(win, y1, x1 + 1 - strlen(buf), buf);
    snprintf(buf, sizeof(buf), "%d%%-%d%%",
             static_cast<int>(histogram->LowCumDensity() * 100),
             static_cast<int>(histogram->HighCumDensity() * 100));
    mvwaddstr(win, y1, x0, buf);
    // Draw Y axis labels
    const float hist_ymax = y1 - 1;
    const float hist_ymin = y0 + 1;
    const int max_histogram_h = histogram->MaxBucketHeight();
    if (hist_ymax <= hist_ymin)
        return; // Not enough space for rendering
    if (max_histogram_h <= 0)
        return;
    bool LOG_TRANSFORM = true;
    float lg_maxh = 0;
    if (LOG_TRANSFORM)
    {
        lg_maxh = log(max_histogram_h);
    }
    for (int y = hist_ymin; y <= hist_ymax; y++)
    {
        // There are (hist_ymax - hist_ymin + 1) divisions
        float fullness;
        fullness = (hist_ymax - y + 1) * 1.0f / (hist_ymax - hist_ymin + 1);
        int h;
        if (!LOG_TRANSFORM)
        {
            h = static_cast<int>(max_histogram_h * fullness);
        }
        else
        {
            h = static_cast<int>(exp(fullness * lg_maxh));
        }
        snprintf(buf, sizeof(buf), "%6d-", h);
        mvwaddstr(win, y, x0 + LEFT_MARGIN - strlen(buf), buf);
    }
    const int bar_height = hist_ymax - hist_ymin + 1; // Height of a full bar
    for (int x = x2, bidx = 0; x <= x1; x++, bidx++)
    {
        int h = histogram->BucketHeight(bidx);
        float lines_visible;
        if (!LOG_TRANSFORM)
        {
            lines_visible = h * 1.0f / max_histogram_h * bar_height;
        }
        else
        {
            if (h <= 0)
                lines_visible = 0;
            else
                lines_visible = log(h) * 1.0f / lg_maxh * bar_height;
        }
        // The histogram's top shall start from this line
        int y = hist_ymax - static_cast<int>(lines_visible);
        float y_frac = lines_visible - static_cast<int>(lines_visible);
        char ch; // Last filling character
        if (y >= hist_ymin)
        { // At the maximum bucket the Y overflows, so skip
            if (y_frac >= 0.66f)
            {
                ch = ':';
            }
            else if (y_frac >= 0.33f)
            {
                ch = '.';
            }
            else
            {
                if (y < hist_ymax)
                {
                    ch = ' ';
                }
                else
                {
                    if (y_frac > 0)
                    {
                        ch =
                            '.'; // Makes long-tailed distribution easier to see
                    }
                }
            }
            mvwaddch(win, y, x, ch);
        }
        y++;
        for (; y <= hist_ymax; y++)
        {
            mvwaddch(win, y, x, ':');
        }
    }
}

void SummaryView::UpdateDBusTopStatistics(DBusTopStatistics* stat)
{
    if (!stat)
        return;
    float interval_secs = stat->seconds_since_last_sample_;
    if (interval_secs == 0)
    {
        interval_secs = GetSummaryIntervalInMillises() / 1000.0f;
    }
    // Per-second
    method_call_ = stat->num_mc_ / interval_secs;
    method_return_ = stat->num_mr_ / interval_secs;
    signal_ = stat->num_sig_ / interval_secs;
    error_ = stat->num_error_ / interval_secs;
    total_ = stat->num_messages_ / interval_secs;
    g_bargraph->AddValue(total_);
}

std::string Ellipsize(const std::string& s, int len_limit)
{
    if (len_limit <= 3)
        return s.substr(0, len_limit);
    if (static_cast<int>(s.size()) < len_limit)
    {
        return s;
    }
    else
    {
        return s.substr(0, len_limit - 3) + "...";
    }
}

void SummaryView::Render()
{
    // Draw text
    werase(win);
    if (!visible_)
        return;
    wattron(win, A_BOLD | A_UNDERLINE);
    mvwaddstr(win, 1, 1, "Message Type          | msg/s");
    wattrset(win, 0);
    const int xend = 30;
    std::string s;
    s = FloatToString(method_call_);
    mvwaddstr(win, 2, 1, "Method Call");
    mvwaddstr(win, 2, xend - s.size(), s.c_str());
    s = FloatToString(method_return_);
    mvwaddstr(win, 3, 1, "Method Return ");
    mvwaddstr(win, 3, xend - s.size(), s.c_str());
    s = FloatToString(signal_);
    mvwaddstr(win, 4, 1, "Signal");
    mvwaddstr(win, 4, xend - s.size(), s.c_str());
    s = FloatToString(error_);
    mvwaddstr(win, 5, 1, "Error ");
    mvwaddstr(win, 5, xend - s.size(), s.c_str());
    wattron(win, A_UNDERLINE);
    s = FloatToString(total_);
    mvwaddstr(win, 6, 1, "Total");
    mvwaddstr(win, 6, xend - s.size(), s.c_str());
    wattroff(win, A_UNDERLINE);
    wattrset(win, 0);
    // Draw history bar graph
    Rect bargraph_rect = rect;
    const int bargraph_x = 64;
    bargraph_rect.x += bargraph_x;
    bargraph_rect.w -= bargraph_x;
    HistoryBarGraph(win, bargraph_rect, g_bargraph);
    // Draw histogram
    Rect histogram_rect = rect;
    histogram_rect.x += 32;
    histogram_rect.w = bargraph_rect.x - histogram_rect.x - 3;
    DrawHistogram(win, histogram_rect, g_histogram);
    // Draw border between summary and histogram
    for (int y = bargraph_rect.y; y <= bargraph_rect.y + bargraph_rect.h; y++)
    {
        mvwaddch(win, y, histogram_rect.x - 1, '|');
        mvwaddch(win, y, bargraph_rect.x - 1, '|');
    }
    DrawBorderIfNeeded();
    wrefresh(win);
}

void SensorDetailView::Render()
{
    werase(win);
    if (!visible_)
        return;
    // If some sensor is focused, show details regarding that sensor
    if (state == SensorList)
    { // Otherwise show the complete list
        const int ncols = DispSensorsPerRow(); // Number of columns in viewport
        const int nrows = DispSensorsPerColumn(); // # rows in viewport
        int sensors_per_page = nrows * ncols;
        // Just in case the window gets invisibly small
        if (sensors_per_page < 1)
            return;
        int num_sensors = sensor_ids_.size();
        int total_num_columns = (num_sensors - 1) / nrows + 1;
        bool is_cursor_out_of_view = false;
        if (idx0 > choice_ || idx1 <= choice_)
        {
            is_cursor_out_of_view = true;
        }
        if (idx0 == INVALID || idx1 == INVALID)
        {
            is_cursor_out_of_view = true;
        }
        if (is_cursor_out_of_view)
        {
            idx0 = 0, idx1 = sensors_per_page;
        }
        while (idx1 <= choice_)
        {
            idx0 += nrows;
            idx1 += nrows;
        }
        const int y0 = 2; // to account for the border and info line
        const int x0 = 4; // to account for the left overflow marks
        int y = y0, x = x0;
        for (int i = 0; i < sensors_per_page; i++)
        {
            int idx = idx0 + i;
            if (idx < static_cast<int>(sensor_ids_.size()))
            {
                if (idx == choice_)
                {
                    wattrset(win, A_REVERSE);
                }
                std::string s = sensor_ids_[idx];
                if (static_cast<int>(s.size()) > col_width) {
                    s = s.substr(0, col_width - 2) + "..";
                } else {
                    while (static_cast<int>(s.size()) < col_width)
                    {
                        s.push_back(' ');
                    }
                }
                mvwaddstr(win, y, x, s.c_str());
                wattrset(win, 0);
            }
            else
                break;
            y++;
            if (i % nrows == nrows - 1)
            {
                y = y0;
                x += col_width + h_spacing;
            }
        }
        // Print overflow marks to the right of the screen
        for (int i = 0; i < nrows; i++)
        {
            int idx = idx0 + sensors_per_page + i;
            if (idx < num_sensors)
            {
                mvwaddch(win, y0 + i, x, '>');
            }
        }
        // Print overflow marks to the left of the screen
        for (int i = 0; i < nrows; i++)
        {
            int idx = idx0 - nrows + i;
            if (idx >= 0)
            {
                mvwaddch(win, y0 + i, 2, '<');
            }
        }
        // idx1 is one past the visible range, so no need to +1
        const int col0 = idx0 / nrows + 1, col1 = idx1 / nrows;
        mvwprintw(win, 1, 2, "Columns %d-%d of %d", col0, col1,
                  total_num_columns);
        mvwprintw(win, 1, rect.w - 15, "%d sensors", sensor_ids_.size());
    }
    else if (state == SensorDetail)
    {
        // sensor_ids_ is the cached list of sensors, it should be the same size
        // as the actual number of sensors in the snapshot
        mvwprintw(win, 1, 2, "Details of sensor %s", curr_sensor_id_.c_str());
        mvwprintw(win, 1, rect.w - 15, "Sensor %d/%u", choice_ + 1,
                  sensor_ids_.size()); // 1-based
        std::vector<Sensor*> sensors =
            g_sensor_snapshot->FindSensorsBySensorID(curr_sensor_id_);
        const int N = static_cast<int>(sensors.size());
        const int w = rect.w - 5;
        mvwprintw(win, 3, 2, "There are %d sensors with the name %s", N,
                  curr_sensor_id_.c_str());
        int y = 5;
        int x = 2;
        if (N > 0)
        {
            for (int j = 0; j < N; j++)
            {
                Sensor* sensor = sensors[j];
                mvwprintw(win, y, x, "%d/%d", j + 1, N);
                char buf[200];
                snprintf(buf, sizeof(buf), "DBus Service    : %s",
                         sensor->ServiceName().c_str());
                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
                snprintf(buf, sizeof(buf), "DBus Connection : %s",
                         sensor->ConnectionName().c_str());
                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
                snprintf(buf, sizeof(buf), "DBus Object Path: %s",
                         sensor->ObjectPath().c_str());
                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
                y++;
            }
        }
        else
        {
            mvwaddstr(win, y, x, "Sensor details not found");
        }
    }
    DrawBorderIfNeeded();
    wrefresh(win);
}

std::string SensorDetailView::GetStatusString()
{
    if (state == SensorList)
    {
        return "[Arrow Keys]=Move Cursor [Q]=Deselect [Enter]=Show Sensor "
               "Detail";
    }
    else
    {
        return "[Arrow Keys]=Cycle Through Sensors [Esc/Q]=Exit";
    }
}

DBusStatListView::DBusStatListView() : DBusTopWindow()
{
    highlight_col_idx_ = 0;
    sort_col_idx_ = 0;
    sort_order_ = SortOrder::Ascending;
    horizontal_pan_ = 0;
    row_idx_ = INVALID;
    disp_row_idx_ = 0;
    horizontal_pan_ = 0;
    menu1_ = new ArrowKeyNavigationMenu(this);
    menu2_ = new ArrowKeyNavigationMenu(this);
    // Load all available field names
    std::set<std::string> inactive_fields;
    std::set<std::string> active_fields;

    // Default choice of field names
    const int N = static_cast<int>(sizeof(FieldNames) / sizeof(FieldNames[0]));
    for (int i = 0; i < N; i++)
    {
        inactive_fields.insert(FieldNames[i]);
    }
    for (const std::string& s :
         dbus_top_analyzer::g_dbus_statistics.GetFieldNames())
    {
        inactive_fields.erase(s);
        active_fields.insert(s);
    }
    for (int i = 0; i < N; i++)
    {
    const std::string s = FieldNames[i];
        if (inactive_fields.count(s) > 0)
        {
            menu1_->AddItem(s);
        }
        else
        {
            menu2_->AddItem(s);
        }
    }
    
    curr_menu_state_ = LeftSide;
    menu_h_ = 5;
    menu_w_ = 24; // Need at least 2*padding + 15 for enough space, see menu.hpp
    menu_margin_ = 6;
    // Populate preferred column widths
    for (int i = 0; i < N; i++)
    {
        column_widths_[FieldNames[i]] = FieldPreferredWidths[i];
    }
}

std::pair<int, int> DBusStatListView::GetXSpanForColumn(const int col_idx)
{
    std::vector<int> cw = ColumnWidths();
    if (col_idx < 0 || col_idx >= static_cast<int>(cw.size()))
    {
        return std::make_pair(INVALID, INVALID);
    }
    int x0 = 0, x1 = 0;
    for (int i = 0; i < col_idx; i++)
    {
        if (i > 0)
        {
            x0 += cw[i];
        }
    }
    x1 = x0 + cw[col_idx] - 1;
    return std::make_pair(x0, x1);
}

// If tolerance > 0, consider overlap before 2 intervals intersect
// If tolerance ==0, consider overlap if 2 intervals exactly intersect
// If tolerance < 0, consider overlap if Minimal Translate Distance is >=
// -threshold
bool IsSpansOverlap(const std::pair<int, int>& s0,
                    const std::pair<int, int>& s1, int tolerance)
{
    if (tolerance >= 0)
    {
        if (s0.second < s1.first - tolerance)
            return false;
        else if (s1.second < s0.first - tolerance)
            return false;
        else
            return true;
    }
    else
    {
        // Compute overlapping distance
        std::vector<std::pair<int, int>> tmp(
            4); // [x, 1] means the start of interval
                // [x,-1] means the end of interval
        tmp[0] = std::make_pair(s0.first, 1);
        tmp[1] = std::make_pair(s0.second, -1);
        tmp[2] = std::make_pair(s1.first, 1);
        tmp[3] = std::make_pair(s1.second, -1);
        std::sort(tmp.begin(), tmp.end());
        int overlap_x0 = -INVALID, overlap_x1 = -INVALID;
        int idx = 0;
        const int N = static_cast<int>(tmp.size());
        int level = 0;
        while (idx < N)
        {
            const int x = tmp[idx].first;
            while (idx < N && x == tmp[idx].first)
            {
                level += tmp[idx].second;
                idx++;
            }
            // The starting position of the overlap
            if (level == 2)
            {
                overlap_x0 = idx - 1;
            }
            // The ending position of the overlap
            if (overlap_x0 != -INVALID && level < 2 && overlap_x1 == -INVALID)
            {
                overlap_x1 = idx - 1;
            }
        }
        const int overlap_length = overlap_x1 - overlap_x0 + 1;
        if (overlap_length >= -tolerance)
            return true;
        else
            return false;
    }
}

bool DBusStatListView::IsXSpanVisible(const std::pair<int, int>& xs,
                                      int tolerance)
{
    const std::pair<int, int> vxs = {horizontal_pan_, horizontal_pan_ + rect.w};
    return IsSpansOverlap(xs, vxs, tolerance);
}
std::vector<std::string> DBusStatListView::ColumnHeaders()
{
    return visible_columns_;
}

std::vector<int> DBusStatListView::ColumnWidths()
{
    std::vector<int> widths = {8}; // for "Msg/s"
    std::vector<std::string> agg_headers = visible_columns_;
    std::vector<int> agg_widths(agg_headers.size(), 0);
    for (int i = 0; i < static_cast<int>(agg_headers.size()); i++)
    {
        agg_widths[i] = column_widths_[agg_headers[i]];
    }
    widths.insert(widths.end(), agg_widths.begin(), agg_widths.end());
    return widths;
}

// Coordinate systems are in world space, +x faces to the right
// Viewport:            [horizontal_pan_,   horizontal_pan_ + rect.w]
// Contents:  [  column_width[0]  ][  column_width[1] ][  column_width[2]  ]
void DBusStatListView::PanViewportOrMoveHighlightedColumn(const int delta_x)
{
    // If the column to the left is visible, highlight it
    const int N = static_cast<int>(ColumnHeaders().size());
    bool col_idx_changed = false;
    if (delta_x < 0)
    { // Pan left
        if (highlight_col_idx_ > 0)
        {
            std::pair<int, int> xs_left =
                GetXSpanForColumn(highlight_col_idx_ - 1);
            if (IsXSpanVisible(xs_left, -1))
            {
                highlight_col_idx_--;
                col_idx_changed = true;
            }
        }
        if (!col_idx_changed)
        {
            horizontal_pan_ += delta_x;
        }
    }
    else if (delta_x > 0)
    { // Pan right
        if (highlight_col_idx_ < N - 1)
        {
            std::pair<int, int> xs_right =
                GetXSpanForColumn(highlight_col_idx_ + 1);
            if (IsXSpanVisible(xs_right, -1))
            {
                highlight_col_idx_++;
                col_idx_changed = true;
            }
        }
        if (!col_idx_changed)
        {
            horizontal_pan_ += delta_x;
        }
    }
}

void DBusStatListView::OnKeyDown(const std::string& key)
{
    {
        switch (curr_menu_state_)
        {
            case LeftSide:
            {
                if (key == "up")
                {
                    menu1_->OnKeyDown("up");
                }
                else if (key == "down")
                {
                    menu1_->OnKeyDown("down");
                }
                else if (key == "right")
                {
                    SetMenuState(RightSide);
                }
                else if (key == "enter")
                {
                    SetMenuState(Hidden);
                }
                else if (key == "space")
                {
                    std::string ch;
                    if (menu1_->RemoveHighlightedItem(&ch))
                    {
                        menu2_->AddItem(ch);
                    }
                }
                break;
            }
            case RightSide:
            {
                if (key == "up")
                {
                    menu2_->OnKeyDown("up");
                }
                else if (key == "down")
                {
                    menu2_->OnKeyDown("down");
                }
                else if (key == "left")
                {
                    SetMenuState(LeftSide);
                }
                else if (key == "enter")
                {
                    SetMenuState(Hidden);
                }
                else if (key == "space")
                {
                    std::string ch;
                    if (menu2_->RemoveHighlightedItem(&ch))
                    {
                        menu1_->AddItem(ch);
                    }
                }
                break;
            }
            case Hidden:
            {
                if (key == "enter")
                {
                    switch (last_menu_state_)
                    {
                        case LeftSide:
                        case RightSide:
                            SetMenuState(last_menu_state_);
                            break;
                        default:
                            SetMenuState(LeftSide);
                    }
                }
                else if (key == "left")
                {
                    PanViewportOrMoveHighlightedColumn(-2);
                }
                else if (key == "right")
                {
                    PanViewportOrMoveHighlightedColumn(2);
                }
                else if (key == "up")
                {
                    disp_row_idx_--;
                    if (disp_row_idx_ < 0)
                    {
                        disp_row_idx_ = 0;
                    }
                }
                else if (key == "down")
                {
                    disp_row_idx_++;
                    const int N = static_cast<int>(stats_snapshot_.size());
                    if (disp_row_idx_ >= N)
                    {
                        disp_row_idx_ = N - 1;
                    }
                }
                else if (key == "a")
                {
                    sort_order_ = SortOrder::Ascending;
                    sort_col_idx_ = highlight_col_idx_;
                    break;
                }
                else if (key == "d")
                {
                    sort_order_ = SortOrder::Descending;
                    sort_col_idx_ = highlight_col_idx_;
                    break;
                }
                break;
            }
        }
    }
    Render();
}

// Window C
void DBusStatListView::Render()
{
    werase(win);
    if (!visible_)
        return;
    int num_lines_shown = rect.h - 3;
    if (curr_menu_state_ == LeftSide || curr_menu_state_ == RightSide)
    {
        menu1_->Render();
        menu2_->Render();
        num_lines_shown -= (menu_h_ + 3);
        // Draw the arrow
        const int x1 = menu1_->rect_.x;
        const int h1 = menu1_->rect_.h;
        const int x2 = menu2_->rect_.x;
        const int w2 = menu2_->rect_.w;
        const int y1 = menu1_->rect_.y;
        const int arrow_x = (x1 + x2 + w2) / 2 - 2;
        const int arrow_y = y1 + 2;
        const int caption_x = x1;
        const int caption_y = y1 + h1;
        for (int x = 1; x < rect.w - 1; x++)
        {
            mvwaddch(win, y1 - 3, x, '-');
        }
        mvwaddstr(win, y1 - 3, arrow_x - 8, "Press [Enter] to show/hide");
        mvwaddstr(win, y1 - 2, caption_x - 5,
                  "DBus fields for aggregating and sorting results:");
        if (curr_menu_state_ == LeftSide)
        {
            mvwaddstr(win, y1 - 1, x1 - 4, "--[ Available Fields ]--");
            mvwaddstr(win, y1 - 1, x2 - 4, "--- Active Fields ---");
        }
        else
        {
            mvwaddstr(win, y1 - 1, x1 - 4, "--- Available Fields ---");
            mvwaddstr(win, y1 - 1, x2 - 4, "--[ Active Fields ]--");
        }
        if (curr_menu_state_ == LeftSide)
        {
            mvwaddstr(win, arrow_y, arrow_x, "-->");
            mvwaddstr(win, caption_y, caption_x,
                      "Press [Space] to move to the right");
        }
        else
        {
            mvwaddstr(win, arrow_y, arrow_x, "<--");
            mvwaddstr(win, caption_y, caption_x,
                      "Press [Space] to move to the left");
        }
    }
    std::vector<std::string> headers;
    std::vector<int> widths;
    visible_columns_ = g_dbus_statistics->GetFieldNames();
    std::vector<std::string> agg_headers = visible_columns_;
    std::vector<int> agg_widths(agg_headers.size(), 0);
    for (int i = 0; i < static_cast<int>(agg_headers.size()); i++)
    {
        agg_widths[i] = column_widths_[agg_headers[i]];
    }
    headers.insert(headers.end(), agg_headers.begin(), agg_headers.end());
    widths.insert(widths.end(), agg_widths.begin(), agg_widths.end());
    std::vector<int> xs;
    int curr_x = 2 - horizontal_pan_;
    for (const int w : widths)
    {
        xs.push_back(curr_x);
        curr_x += w;
    }
    const int N = headers.size();
    // Bound col_idx_
    if (highlight_col_idx_ >= N)
    {
        highlight_col_idx_ = N - 1;
    }
    // Render column headers
    for (int i = 0; i < N; i++)
    {
        std::string s = headers[i];
        // 1 char outside boundary = start printing from the second character,
        // etc

        // Print "<" for Ascending order (meaning: row 0 < row 1 < row 2 ... )
        // Print ">" for Descending order (meaning: row 0 > row 1 > row 2 ... )
        if (sort_col_idx_ == i)
        {
            if (sort_order_ == SortOrder::Ascending)
            {
                s.push_back('<');
            }
            else
            {
                s.push_back('>');
            }
        }

        // Highlight the "currently-selected column"
        if (highlight_col_idx_ == i)
        {
            wattrset(win, 0);
            wattron(win, A_REVERSE);
        }
        else
        {
            wattrset(win, 0);
            wattron(win, A_UNDERLINE);
        }
        int x = xs[i];
        if (x < 0)
        {
            if (-x < static_cast<int>(s.size()))
            {
                s = s.substr(-x);
            }
            else
                s = "";
            x = 0;
        }
        mvwaddstr(win, 1, x, s.c_str());
    }
    wattrset(win, 0);
    // Time since the last update of Window C
    float interval_secs = g_dbus_statistics->seconds_since_last_sample_;
    if (interval_secs == 0)
    {
        interval_secs = GetSummaryIntervalInMillises() / 1000.0f;
    }

    stats_snapshot_ = g_dbus_statistics->StatsSnapshot();
    const int nrows = static_cast<int>(stats_snapshot_.size());
    const std::vector<DBusTopSortField> fields = g_dbus_statistics->GetFields();
    const int ncols = static_cast<int>(fields.size());
    // Merge the list of DBus Message properties & computed metrics together
    std::map<std::vector<std::string>, DBusTopComputedMetrics>::iterator itr =
        stats_snapshot_.begin();
    struct StringOrFloat
    { // Cannot use union so using struct
        std::string s;
        float f;
    };

    // "Stage" the snapshot for displaying in the form of a spreadsheet
    std::vector<std::pair<StringOrFloat, std::vector<std::string>>>
        stats_snapshot_staged;
    const DBusTopSortField sort_field = fields[sort_col_idx_];
    const bool is_sort_key_numeric = DBusTopSortFieldIsNumeric(sort_field);

    for (int i = 0; i < nrows; i++) // One row of cells
    {
        int idx0 = 0; // indexing into the std::vector<string> of each row
        std::vector<std::string> row;

        StringOrFloat sort_key; // The key used for sorting
        for (int j = 0; j < ncols; j++) // one column in the row
        {
            DBusTopSortField field = fields[j];
            // Populate the content of stats_snapshot_staged

            StringOrFloat sof; // Represents this column
            
            // When we haven't used up all
            if (idx0 < static_cast<int>(itr->first.size()))
            {
                sof.s = itr->first[idx0];
            }
            switch (field)
            {
                case kSender:      // string
                case kDestination: // string
                case kInterface:   // string
                case kPath:        // string
                case kMember:      // string
                case kSenderPID:   // numeric
                case kSenderCMD:   // string
                    row.push_back(itr->first[idx0]);
                    idx0++;
                    if (field == kSenderPID)
                    {
                        // Note: attempting to std::atof("(unknown)") on the BMC
                        // will cause hang. And GDB won't show backtrace.
                        if (sof.s == "(unknown)")
                        {
                            if (sort_order_ == Ascending)
                            {
                                sof.f = -1;
                            }
                            else
                            {
                                sof.f = 1e20;
                            }
                        }
                        else
                        {
                            sof.f = std::atof(sof.s.c_str());
                        }
                    }
                    break;
                case kMsgPerSec: // Compute "messages per second"
                {
                    int numbers[] = {
                        itr->second.num_method_calls,
                        itr->second.num_method_returns,
                        itr->second.num_signals,
                        itr->second.num_errors,
                    };
                    int the_sum = 0; // For sorting

                    std::string s; // String representation in the form or
                                   // "1.00/2.00/3.00/4.00"
                    for (int i = 0; i < 4; i++)
                    {
                        the_sum += numbers[i];
                        if (i > 0)
                            s += "/";
                        float per_sec = numbers[i] / interval_secs;
                        s += FloatToString(per_sec);
                    }

                    row.push_back(s);
                    sof.f = the_sum;
                    break;
                }
                case kAverageLatency: // Compute "average Method Call latency"
                    const DBusTopComputedMetrics& m = itr->second;
                    if (m.num_method_calls == 0)
                    {
                        row.push_back("n/a");
                        if (sort_order_ == Ascending)
                        {
                            sof.f = -1; // Put to the top
                        }
                        else
                        {
                            sof.f = 1e20; // Put to the top
                        }
                    }
                    else
                    {
                        float avg_latency_usec =
                            m.total_latency_usec / m.num_method_calls;
                        row.push_back(FloatToString(avg_latency_usec));
                        sof.f = avg_latency_usec;
                    }
                    break;
            }
            if (j == sort_col_idx_)
            {
                sort_key = sof;
            }
        }
        stats_snapshot_staged.push_back(std::make_pair(sort_key, row));
        itr++;
    }
    
    // Sort the "staged snapshot" using the sort_key, using different functions
    // depending on whether sort key is numeric or string
    if (is_sort_key_numeric)
    {
        std::sort(
            stats_snapshot_staged.begin(), stats_snapshot_staged.end(),
            [](const std::pair<StringOrFloat, std::vector<std::string>>& a,
               const std::pair<StringOrFloat, std::vector<std::string>>& b) {
                return a.first.f < b.first.f;
            });
    }
    else
    {
        std::sort(
            stats_snapshot_staged.begin(), stats_snapshot_staged.end(),
            [](const std::pair<StringOrFloat, std::vector<std::string>>& a,
               const std::pair<StringOrFloat, std::vector<std::string>>& b) {
                return a.first.s < b.first.s;
            });
    }
    
    if (sort_order_ == Descending)
    {
        std::reverse(stats_snapshot_staged.begin(),
                     stats_snapshot_staged.end());
    }
    // Minus 2 because of "msgs/s" and "+"
    const int num_fields = N;
    // The Y span of the area for rendering the "spreadsheet"
    const int y0 = 2, y1 = y0 + num_lines_shown - 1;
    // Key is sender, destination, interface, path, etc
    for (int i = 0, shown = 0;
        i + disp_row_idx_ < static_cast<int>(stats_snapshot_staged.size()) &&
        shown < num_lines_shown;
        i++, shown++)
    {
        std::string s;
        int x = 0;
        const std::vector<std::string> key =
            stats_snapshot_staged[i + disp_row_idx_].second;
        for (int j = 0; j < num_fields; j++)
        {
            x = xs[j];
            s = key[j];
            // Determine column width limit for this particular column
            int col_width = 100;
            if (j < num_fields - 1)
            {
                col_width = xs[j + 1] - xs[j] - 1;
            }
            s = Ellipsize(s, col_width);
            if (x < 0)
            {
                if (-x < static_cast<int>(s.size()))
                    s = s.substr(-x);
                else
                    s = "";
                x = 0;
            }
            // Trim if string overflows to the right
            if (x + static_cast<int>(s.size()) > rect.w)
            {
                s = s.substr(0, rect.w - x);
            }
            mvwaddstr(win, 2 + i, x, s.c_str());
        }
    }
    // Overflows past the top ...
    if (disp_row_idx_ > 0)
    {
        std::string x = " [+" + std::to_string(disp_row_idx_) + " rows above]";
        mvwaddstr(win, y0, rect.w - static_cast<int>(x.size()) - 1, x.c_str());
    }
    // Overflows past the bottom ...
    const int last_disp_row_idx = disp_row_idx_ + num_lines_shown - 1;
    if (last_disp_row_idx < nrows - 1)
    {
        std::string x = " [+" +
                        std::to_string((nrows - 1) - last_disp_row_idx) +
                        " rows below]";
        mvwaddstr(win, y1, rect.w - static_cast<int>(x.size()) - 1, x.c_str());
    }
    DrawBorderIfNeeded();
    wrefresh(win);
}

void DBusStatListView::OnResize(int win_w, int win_h)
{
    rect.y = 8 - MARGIN_BOTTOM;
    rect.w = win_w - (win_w / 2) + 1; // Perfectly overlap on the vertical edge
    rect.x = win_w - rect.w;
    rect.h = win_h - rect.y - MARGIN_BOTTOM;
    const int x0 = rect.w / 2 - menu_w_ - menu_margin_ / 2;
    const int x1 = x0 + menu_margin_ + menu_w_;
    const int menu_y = rect.h - menu_h_;
    menu1_->SetRect(Rect(x0, menu_y, menu_w_, menu_h_)); // Local coordinates
    menu1_->SetOrder(ArrowKeyNavigationMenu::Order::ColumnMajor);
    menu2_->SetRect(Rect(x1, menu_y, menu_w_, menu_h_));
    menu2_->SetOrder(ArrowKeyNavigationMenu::Order::ColumnMajor);
    UpdateWindowSizeAndPosition();
}

std::vector<DBusTopSortField> DBusStatListView::GetSortFields()
{
    std::vector<DBusTopSortField> ret;
    const int N = sizeof(FieldNames) / sizeof(FieldNames[0]);
    for (const std::string& s : menu2_->Items())
    {
        for (int i = 0; i < N; i++)
        {
            if (FieldNames[i] == s)
            {
                ret.push_back(static_cast<DBusTopSortField>(i));
                break;
            }
        }
    }
    return ret;
}

std::string DBusStatListView::GetStatusString()
{
    if (curr_menu_state_ == LeftSide || curr_menu_state_ == RightSide)
    {
        return "[Enter]=Hide Panel [Space]=Choose Entry [Arrow Keys]=Move "
               "Cursor";
    }
    else
    {
        return "[Enter]=Show Column Select Panel [Arrow Keys]=Pan View";
    }
}

void FooterView::Render()
{
    werase(win);
    const time_t now = time(nullptr);
    const char* date_time = ctime(&now);
    wattrset(win, 0);
    std::string help_info;
    if (g_current_active_view == nullptr)
    {
        help_info = "Press [Tab] to cycle through views";
    }
    else
    {
        help_info = g_current_active_view->GetStatusString();
    }
    mvwaddstr(win, 0, 1, date_time);
    mvwaddstr(win, 0, rect.w - int(help_info.size()) - 1, help_info.c_str());
    wrefresh(win);
}
