// 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[];
extern bool g_sensor_update_thread_active;
extern std::string g_snapshot_update_bus_cxn;

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, "%zu 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/%zu", 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++;

                // TODO: can cache in and out & only update when there are user
                // UI actions
                std::map<std::string, std::set<std::string>> in, out;
                g_sensor_snapshot->FindAssociationEndpoints(
                    sensor->ObjectPath(), &out, &in);

                y++;
                mvwprintw(win, y, x, "Association status:");

                if (out.size() > 0)
                {
                    y++;
                    int nforward = 0;
                    for (const auto& [k, v] : out)
                    {
                        nforward += int(v.size());
                    }
                    mvwprintw(win, y, x,
                              "Used as Forward vertex %d times:", nforward);
                    y++;
                    int idx = 0;
                    for (const auto& [k, v] : out)
                    {
                        idx++;
                        snprintf(buf, sizeof(buf), "%d. %s (%zu)", idx,
                                 k.c_str(), v.size());
                        y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
                        for (const std::string& entry : v)
                        {
                            y += DrawTextWithWidthLimit(win, entry, y, x + 2,
                                                        w - 2, "/");
                        }
                    }
                }
                else
                {
                    y++;
                    mvwprintw(win, y, x, "Not used as forward vertex");
                    y++;
                }

                if (in.size() > 0)
                {
                    y++;
                    int nbackward = 0;
                    for (const auto& [k, v] : in)
                    {
                        nbackward += int(v.size());
                    }
                    mvwprintw(win, y, x,
                              "Used as reverse vertex %d times:", nbackward);
                    y++;
                    int idx = 0;
                    for (const auto& [k, v] : in)
                    {
                        idx++;
                        snprintf(buf, sizeof(buf), "%d. %s (%zu)", idx,
                                 k.c_str(), v.size());
                        y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
                        for (const std::string& entry : v)
                        {
                            y += DrawTextWithWidthLimit(win, entry, y, x + 2,
                                                        w - 2, "/");
                        }
                    }
                }
                else
                {
                    y++;
                    mvwprintw(win, y, x, "Not used as reverse vertex");
                }
            }
        }
        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, 27, "                                           ");
    mvwaddstr(win, 0, 27, status_string_.c_str());
    mvwaddstr(win, 0, rect.w - int(help_info.size()) - 1, help_info.c_str());
    wrefresh(win);
}
