// Copyright (C) 2023 The Android Open Source Project
//
// 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.

import m from 'mithril';

import {searchSegment} from '../base/binary_search';
import {Disposable, NullDisposable} from '../base/disposable';
import {assertTrue, assertUnreachable} from '../base/logging';
import {duration, Time, time} from '../base/time';
import {drawTrackHoverTooltip} from '../common/canvas_utils';
import {raf} from '../core/raf_scheduler';
import {EngineProxy, LONG, NUM, Track} from '../public';
import {Button} from '../widgets/button';
import {MenuItem, MenuDivider, PopupMenu2} from '../widgets/menu';

import {checkerboardExcept} from './checkerboard';
import {globals} from './globals';
import {PanelSize} from './panel';
import {constraintsToQuerySuffix} from './sql_utils';
import {NewTrackArgs} from './track';
import {CacheKey, TimelineCache} from '../core/timeline_cache';
import {featureFlags} from '../core/feature_flags';

export const COUNTER_DEBUG_MENU_ITEMS = featureFlags.register({
  id: 'counterDebugMenuItems',
  name: 'Counter debug menu items',
  description: 'Extra counter menu items for debugging purposes.',
  defaultValue: false,
});

function roundAway(n: number): number {
  const exp = Math.ceil(Math.log10(Math.max(Math.abs(n), 1)));
  const pow10 = Math.pow(10, exp);
  return Math.sign(n) * (Math.ceil(Math.abs(n) / (pow10 / 4)) * (pow10 / 4));
}

function toLabel(n: number): string {
  if (n === 0) {
    return '0';
  }
  const units: [number, string][] = [
    [0.000000001, 'n'],
    [0.000001, 'u'],
    [0.001, 'm'],
    [1, ''],
    [1000, 'K'],
    [1000*1000, 'M'],
    [1000*1000*1000, 'G'],
    [1000*1000*1000*1000, 'T'],
  ];
  let largestMultiplier;
  let largestUnit;
  [largestMultiplier, largestUnit] = units[0];
  for (const [multiplier, unit] of units) {
    if (multiplier >= n) {
      break;
    }
    [largestMultiplier, largestUnit] = [multiplier, unit];
  }
  return `${Math.round(n/largestMultiplier)}${largestUnit}`;
}

class RangeSharer {
  static singleton?: RangeSharer;

  static get(): RangeSharer {
    if (RangeSharer.singleton === undefined) {
      RangeSharer.singleton = new RangeSharer();
    }
    return RangeSharer.singleton;
  }

  private tagToRange: Map<string, [number, number]>;
  private keyToEnabled: Map<string, boolean>;

  constructor() {
    this.tagToRange = new Map();
    this.keyToEnabled = new Map();
  }

  isEnabled(key: string): boolean {
    const value = this.keyToEnabled.get(key);
    if (value === undefined) {
      return true;
    }
    return value;
  }

  setEnabled(key: string, enabled: boolean): void {
    this.keyToEnabled.set(key, enabled);
  }

  share(options: CounterOptions, [min, max]: [number, number]):
      [number, number] {
    const key = options.yRangeSharingKey;
    if (key === undefined || !this.isEnabled(key)) {
      return [min, max];
    }

    const tag = `${options.yRangeSharingKey}-${options.yMode}-${options.yDisplay}-${!!options.enlarge}`;
    const cachedRange = this.tagToRange.get(tag);
    if (cachedRange === undefined) {
      this.tagToRange.set(tag, [min, max]);
      return [min, max];
    }

    cachedRange[0] = Math.min(min, cachedRange[0]);
    cachedRange[1] = Math.max(max, cachedRange[1]);

    return [cachedRange[0], cachedRange[1]];
  }
}

interface CounterData {
  timestamps: BigInt64Array;
  counts: Uint32Array;
  avgValues: Float64Array;
  minDisplayValues: Float64Array;
  maxDisplayValues: Float64Array;
  lastDisplayValues: Float64Array;
  displayValueRange: [number, number];
}

// 0.5 Makes the horizontal lines sharp.
const MARGIN_TOP = 3.5;

interface CounterLimits {
  maxDisplayValue: number;
  minDisplayValue: number;
  maxDurNs: duration;
}

interface CounterTooltipState {
  lastDisplayValue: number;
  avgValue: number;
  count: number;
  ts: time;
  tsEnd?: time;
}

export interface CounterOptions {
  // Mode for computing the y value. Options are:
  // value = v[t] directly the value of the counter at time t
  // delta = v[t] - v[t-1] delta between value and previous value
  // rate = (v[t] - v[t-1]) / dt as delta but normalized for time
  yMode: 'value'|'delta'|'rate';

  // Whether Y scale should cover all of the possible values (and therefore, be
  // static) or whether it should be dynamic and cover only the visible values.
  yRange: 'all'|'viewport';

  // Whether the Y scale should:
  // zero = y-axis scale should cover the origin (zero)
  // minmax = y-axis scale should cover just the range of yRange
  // log = as minmax but also use a log scale
  yDisplay: 'zero'|'minmax'|'log';

  // Whether the range boundaries should be strict and use the precise min/max
  // values or whether they should be rounded down/up to the nearest human
  // readable value.
  yRangeRounding: 'strict'|'human_readable';

  // Allows *extending* the range of the y-axis counter increasing
  // the maximum (via yOverrideMaximum) or decreasing the minimum
  // (via yOverrideMinimum). This is useful for percentage counters
  // where the range (0-100) is known statically upfront and even if
  // the trace only includes smaller values.
  yOverrideMaximum?: number;
  yOverrideMinimum?: number;

  // If set all counters with the same key share a range.
  yRangeSharingKey?: string;

  // Show the chart as 4x the height.
  enlarge?: boolean;

  // unit for the counter. This is displayed in the tooltip and
  // legend.
  unit?: string;
}

export type BaseCounterTrackArgs = NewTrackArgs & {
  options?: Partial<CounterOptions>;
};

export abstract class BaseCounterTrack implements Track {
  protected engine: EngineProxy;
  protected trackKey: string;

  // This is the over-skirted cached bounds:
  private countersKey: CacheKey = CacheKey.zero();

  private counters: CounterData = {
    timestamps: new BigInt64Array(0),
    counts: new Uint32Array(0),
    avgValues: new Float64Array(0),
    minDisplayValues: new Float64Array(0),
    maxDisplayValues: new Float64Array(0),
    lastDisplayValues: new Float64Array(0),
    displayValueRange: [0, 0],
  };

  private cache: TimelineCache<CounterData> = new TimelineCache(5);

  // Cleanup hook for onInit.
  private initState?: Disposable;

  private limits?: CounterLimits;

  private mousePos = {x: 0, y: 0};
  private hover?: CounterTooltipState;
  private defaultOptions: Partial<CounterOptions>;
  private options?: CounterOptions;

  private getCounterOptions(): CounterOptions {
    if (this.options === undefined) {
      const options = this.getDefaultCounterOptions();
      for (const [key, value] of Object.entries(this.defaultOptions)) {
        if (value !== undefined) {
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          (options as any)[key] = value;
        }
      }
      this.options = options;
    }
    return this.options;
  }

  // Extension points.

  // onInit hook lets you do asynchronous set up e.g. creating a table
  // etc. We guarantee that this will be resolved before doing any
  // queries using the result of getSqlSource(). All persistent
  // state in trace_processor should be cleaned up when dispose is
  // called on the returned hook.
  async onInit(): Promise<Disposable> {
    return new NullDisposable();
  }

  // This should be an SQL expression returning the columns `ts` and `value`.
  abstract getSqlSource(): string;

  protected getDefaultCounterOptions(): CounterOptions {
    return {
      yRange: 'all',
      yRangeRounding: 'human_readable',
      yMode: 'value',
      yDisplay: 'zero',
    };
  }

  constructor(args: BaseCounterTrackArgs) {
    this.engine = args.engine;
    this.trackKey = args.trackKey;
    this.defaultOptions = args.options ?? {};
  }

  getHeight() {
    const height = 40;
    return this.getCounterOptions().enlarge ? height * 4: height;
  }

  // A method to render menu items for switching the defualt
  // rendering options.  Useful if a subclass wants to incorporate it
  // as a submenu.
  protected getCounterContextMenuItems(): m.Children {
    const options = this.getCounterOptions();

    return [

      m(MenuItem,
        {
          label: `Display (currently: ${options.yDisplay})`,
        },

        m(MenuItem, {
          label: 'Zero-based',
          icon: (options.yDisplay === 'zero') ? 'radio_button_checked' : 'radio_button_unchecked',
          onclick: () => {
            options.yDisplay = 'zero';
            this.invalidate();
          },
        }),

        m(MenuItem, {
          label: 'Min/Max',
          icon: (options.yDisplay === 'minmax') ? 'radio_button_checked' : 'radio_button_unchecked',
          onclick: () => {
            options.yDisplay = 'minmax';
            this.invalidate();
          },
        }),

        m(MenuItem, {
          label: 'Log',
          icon: (options.yDisplay === 'log') ? 'radio_button_checked' : 'radio_button_unchecked',
          onclick: () => {
            options.yDisplay = 'log';
            this.invalidate();
          },
        }),

      ),

      m(MenuItem, {
        label: 'Zoom on scroll',
        icon: (options.yRange === 'viewport') ? 'check_box' : 'check_box_outline_blank',
        onclick: () => {
          options.yRange = options.yRange === 'viewport' ? 'all' : 'viewport';
          this.invalidate();
        },
      }),

      m(MenuItem, {
        label: `Enlarge`,
        icon: options.enlarge ? 'check_box' : 'check_box_outline_blank',
        onclick: () => {
          options.enlarge = !options.enlarge;
          this.invalidate();
        },
      }),

      options.yRangeSharingKey && m(MenuItem, {
        label: `Share y-axis scale (group: ${options.yRangeSharingKey})`,
        icon: RangeSharer.get().isEnabled(options.yRangeSharingKey) ? 'check_box' : 'check_box_outline_blank',
        onclick: () => {
          const key = options.yRangeSharingKey;
          if (key === undefined) {
            return;
          }
          const sharer = RangeSharer.get();
          sharer.setEnabled(key, !sharer.isEnabled(key));
          this.invalidate();
        },
      }),


      COUNTER_DEBUG_MENU_ITEMS.get() && [
        m(MenuDivider),
        m(MenuItem,
          {
            label: `Mode (currently: ${options.yMode})`,
          },

          m(MenuItem, {
            label: 'Value',
            icon: (options.yMode === 'value') ? 'radio_button_checked' : 'radio_button_unchecked',
            onclick: () => {
              options.yMode = 'value';
              this.invalidate();
            },
          }),

          m(MenuItem, {
            label: 'Delta',
            icon: (options.yMode === 'delta') ? 'radio_button_checked' : 'radio_button_unchecked',
            onclick: () => {
              options.yMode = 'delta';
              this.invalidate();
            },
          }),

          m(MenuItem, {
            label: 'Rate',
            icon: (options.yMode === 'rate') ? 'radio_button_checked' : 'radio_button_unchecked',
            onclick: () => {
              options.yMode = 'rate';
              this.invalidate();
            },
          }),
        ),
        m(MenuItem, {
          label: 'Round y-axis scale',
          icon: (options.yRangeRounding === 'human_readable') ? 'check_box' : 'check_box_outline_blank',
          onclick: () => {
            options.yRangeRounding = options.yRangeRounding === 'human_readable' ? 'strict' : 'human_readable';
            this.invalidate();
          },
        }),
      ],
    ];
  }

  protected invalidate() {
    this.limits = undefined;
    this.cache.invalidate();
    this.countersKey = CacheKey.zero();
    this.counters = {
      timestamps: new BigInt64Array(0),
      counts: new Uint32Array(0),
      avgValues: new Float64Array(0),
      minDisplayValues: new Float64Array(0),
      maxDisplayValues: new Float64Array(0),
      lastDisplayValues: new Float64Array(0),
      displayValueRange: [0, 0],
    };
    this.hover = undefined;

    raf.scheduleFullRedraw();
  }

  // A method to render a context menu corresponding to switching the rendering
  // modes. By default, getTrackShellButtons renders it, but a subclass can call
  // it manually, if they want to customise rendering track buttons.
  protected getCounterContextMenu(): m.Child {
    return m(
      PopupMenu2,
      {
        trigger: m(Button, {icon: 'show_chart', minimal: true}),
      },
      this.getCounterContextMenuItems(),
    );
  }

  getTrackShellButtons(): m.Children {
    return [
      this.getCounterContextMenu(),
    ];
  }

  async onCreate(): Promise<void> {
    this.initState = await this.onInit();
  }

  async onUpdate(): Promise<void> {
    const {
      visibleTimeScale: timeScale,
      visibleWindowTime: vizTime,
    } = globals.timeline;

    const windowSizePx = Math.max(1, timeScale.pxSpan.delta);
    const rawStartNs = vizTime.start.toTime();
    const rawEndNs = vizTime.end.toTime();
    const rawCountersKey = CacheKey.create(rawStartNs, rawEndNs, windowSizePx);

    // If the visible time range is outside the cached area, requests
    // asynchronously new data from the SQL engine.
    await this.maybeRequestData(rawCountersKey);
  }

  render(ctx: CanvasRenderingContext2D, size: PanelSize) {
    const {
      visibleTimeScale: timeScale,
      // visibleWindowTime: vizTime,
    } = globals.timeline;

    // In any case, draw whatever we have (which might be stale/incomplete).

    const limits = this.limits;
    const data = this.counters;

    if (data.timestamps.length === 0 || limits === undefined) {
      return;
    }

    assertTrue(data.timestamps.length === data.counts.length);
    assertTrue(data.timestamps.length === data.avgValues.length);
    assertTrue(data.timestamps.length === data.minDisplayValues.length);
    assertTrue(data.timestamps.length === data.maxDisplayValues.length);
    assertTrue(data.timestamps.length === data.lastDisplayValues.length);

    const options = this.getCounterOptions();

    const timestamps = data.timestamps;
    const minValues = data.minDisplayValues;
    const maxValues = data.maxDisplayValues;
    const lastValues = data.lastDisplayValues;

    // Choose a range for the y-axis
    const {yRange, yMin, yMax, yLabel} =
      this.computeYRange(limits, data.displayValueRange);

    const effectiveHeight = this.getHeight() - MARGIN_TOP;
    const endPx = size.width;
    const hasZero = yMin < 0 && yMax > 0;
    let zeroY = effectiveHeight + MARGIN_TOP;
    if (hasZero) {
      zeroY = effectiveHeight * (yMax / (yMax - yMin)) + MARGIN_TOP;
    }

    // There are 360deg of hue. We want a scale that starts at green with
    // exp <= 3 (<= 1KB), goes orange around exp = 6 (~1MB) and red/violet
    // around exp >= 9 (1GB).
    // The hue scale looks like this:
    // 0                              180                                 360
    // Red        orange         green | blue         purple          magenta
    // So we want to start @ 180deg with pow=0, go down to 0deg and then wrap
    // back from 360deg back to 180deg.
    const exp = Math.ceil(Math.log10(Math.max(yMax, 1)));
    const expCapped = Math.min(Math.max(exp - 3), 9);
    const hue = (180 - Math.floor(expCapped * (180 / 6)) + 360) % 360;

    ctx.fillStyle = `hsl(${hue}, 45%, 75%)`;
    ctx.strokeStyle = `hsl(${hue}, 45%, 45%)`;

    const calculateX = (ts: time) => {
      return Math.floor(timeScale.timeToPx(ts));
    };
    const calculateY = (value: number) => {
      return MARGIN_TOP + effectiveHeight -
          Math.round(((value - yMin) / yRange) * effectiveHeight);
    };

    ctx.beginPath();
    const timestamp = Time.fromRaw(timestamps[0]);
    ctx.moveTo(calculateX(timestamp), zeroY);
    let lastDrawnY = zeroY;
    for (let i = 0; i < timestamps.length; i++) {
      const timestamp = Time.fromRaw(timestamps[i]);
      const x = calculateX(timestamp);
      const minY = calculateY(minValues[i]);
      const maxY = calculateY(maxValues[i]);
      const lastY = calculateY(lastValues[i]);

      ctx.lineTo(x, lastDrawnY);
      if (minY === maxY) {
        assertTrue(lastY === minY);
        ctx.lineTo(x, lastY);
      } else {
        ctx.lineTo(x, minY);
        ctx.lineTo(x, maxY);
        ctx.lineTo(x, lastY);
      }
      lastDrawnY = lastY;
    }
    ctx.lineTo(endPx, lastDrawnY);
    ctx.lineTo(endPx, zeroY);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();

    if (hasZero) {
      // Draw the Y=0 dashed line.
      ctx.strokeStyle = `hsl(${hue}, 10%, 71%)`;
      ctx.beginPath();
      ctx.setLineDash([2, 4]);
      ctx.moveTo(0, zeroY);
      ctx.lineTo(endPx, zeroY);
      ctx.closePath();
      ctx.stroke();
      ctx.setLineDash([]);
    }
    ctx.font = '10px Roboto Condensed';

    const hover = this.hover;
    if (hover !== undefined) {
      let text = `${hover.avgValue.toLocaleString()}`;

      const unit = this.unit;
      switch (options.yMode) {
      case 'value':
        text = `${text} ${unit}`;
        break;
      case 'delta':
        text = `${text} \u0394${unit}`;
        break;
      case 'rate':
        text = `${text} \u0394${unit}/s`;
        break;
      default:
        assertUnreachable(options.yMode);
        break;
      }

      if (hover.count > 1) {
        text += ` (avg of ${hover.count})`;
      }

      ctx.fillStyle = `hsl(${hue}, 45%, 75%)`;
      ctx.strokeStyle = `hsl(${hue}, 45%, 45%)`;

      const xStart = Math.floor(timeScale.timeToPx(hover.ts));
      const xEnd = hover.tsEnd === undefined ?
        endPx :
        Math.floor(timeScale.timeToPx(hover.tsEnd));
      const y = MARGIN_TOP + effectiveHeight -
          Math.round(((hover.lastDisplayValue - yMin) / yRange) *
                     effectiveHeight);

      // Highlight line.
      ctx.beginPath();
      ctx.moveTo(xStart, y);
      ctx.lineTo(xEnd, y);
      ctx.lineWidth = 3;
      ctx.stroke();
      ctx.lineWidth = 1;

      // Draw change marker.
      ctx.beginPath();
      ctx.arc(
        xStart, y, 3 /* r*/, 0 /* start angle*/, 2 * Math.PI /* end angle*/);
      ctx.fill();
      ctx.stroke();

      // Draw the tooltip.
      drawTrackHoverTooltip(ctx, this.mousePos, this.getHeight(), text);
    }

    // Write the Y scale on the top left corner.
    ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';
    ctx.fillRect(0, 0, 42, 16);
    ctx.fillStyle = '#666';
    ctx.textAlign = 'left';
    ctx.textBaseline = 'alphabetic';
    ctx.fillText(`${yLabel}`, 5, 14);

    // TODO(hjd): Refactor this into checkerboardExcept
    {
      const counterEndPx = Infinity;
      // Grey out RHS.
      if (counterEndPx < endPx) {
        ctx.fillStyle = '#0000001f';
        ctx.fillRect(counterEndPx, 0, endPx - counterEndPx, this.getHeight());
      }
    }

    // If the cached trace slices don't fully cover the visible time range,
    // show a gray rectangle with a "Loading..." label.
    checkerboardExcept(
      ctx,
      this.getHeight(),
      0,
      size.width,
      timeScale.timeToPx(this.countersKey.start),
      timeScale.timeToPx(this.countersKey.end));
  }

  onMouseMove(pos: {x: number, y: number}) {
    const data = this.counters;
    if (data === undefined) return;
    this.mousePos = pos;
    const {visibleTimeScale} = globals.timeline;
    const time = visibleTimeScale.pxToHpTime(pos.x);

    const [left, right] = searchSegment(data.timestamps, time.toTime());

    if (left === -1) {
      this.hover = undefined;
      return;
    }

    const ts = Time.fromRaw(data.timestamps[left]);
    const tsEnd = right === -1 ? undefined :
      Time.fromRaw(data.timestamps[right]);
    const lastDisplayValue = data.lastDisplayValues[left];
    const count = data.counts[left];
    const avgValue = data.avgValues[left];
    this.hover = {
      ts,
      tsEnd,
      lastDisplayValue,
      count,
      avgValue,
    };
  }

  onMouseOut() {
    this.hover = undefined;
  }

  onDestroy(): void {
    if (this.initState) {
      this.initState.dispose();
      this.initState = undefined;
    }
  }

  // Compute the range of values to display and range label.
  private computeYRange(limits: CounterLimits, dataLimits: [number, number]): {
    yMin: number,
    yMax: number,
    yRange: number,
    yLabel: string,
  } {
    const options = this.getCounterOptions();

    let yMin = limits.minDisplayValue;
    let yMax = limits.maxDisplayValue;

    if (options.yRange === 'viewport') {
      [yMin, yMax] = dataLimits;
    }

    if (options.yDisplay === 'zero') {
      yMin = Math.min(0, yMin);
    }

    if (options.yOverrideMaximum !== undefined) {
      yMax = Math.max(options.yOverrideMaximum, yMax);
    }

    if (options.yOverrideMinimum !== undefined) {
      yMin = Math.min(options.yOverrideMinimum, yMin);
    }

    if (options.yRangeRounding === 'human_readable') {
      yMax = roundAway(yMax);
      yMin = roundAway(yMin);
    }

    const sharer = RangeSharer.get();
    [yMin, yMax] = sharer.share(options, [yMin, yMax]);

    let yLabel: string;

    if (options.yDisplay === 'minmax') {
      yLabel = 'min - max';
    } else {
      let max = yMax;
      let min = yMin;
      if (options.yDisplay === 'log') {
        max = Math.exp(max);
        min = Math.exp(min);
      }
      const n = Math.abs(max - min);
      yLabel = toLabel(n);
    }

    const unit = this.unit;
    switch (options.yMode) {
    case 'value':
      yLabel += ` ${unit}`;
      break;
    case 'delta':
      yLabel += `\u0394${unit}`;
      break;
    case 'rate':
      yLabel += `\u0394${unit}/s`;
      break;
    default:
      assertUnreachable(options.yMode);
      break;
    }

    if (options.yDisplay === 'log') {
      yLabel = `log(${yLabel})`;
    }

    return {
      yMin,
      yMax,
      yLabel,
      yRange: yMax-yMin,
    };
  }

  // The underlying table has `ts` and `value` columns.
  private getSqlPreamble(): string {
    const options = this.getCounterOptions();

    let valueExpr;

    switch (options.yMode) {
    case 'value':
      valueExpr = 'value';
      break;
    case 'delta':
      valueExpr = 'lead(value, 1, value) over (order by ts) - value';
      break;
    case 'rate':
      valueExpr = '(lead(value, 1, value) over (order by ts) - value) / ((lead(ts, 1, 100) over (order by ts) - ts) / 1e9)';
      break;
    default:
      assertUnreachable(options.yMode);
      break;
    }

    let displayValueExpr = valueExpr;
    if (options.yDisplay === 'log') {
      displayValueExpr = `ifnull(ln(${displayValueExpr}), 0)`;
    }

    return `
      WITH data AS (
        SELECT
          ts,
          ${valueExpr} as value,
          ${displayValueExpr} as displayValue
        FROM (${this.getSqlSource()})
      )
    `;
  }

  private async maybeRequestData(rawCountersKey: CacheKey) {
    let limits = this.limits;
    if (limits === undefined) {
      const maxDurQuery = await this.engine.query(`
        ${this.getSqlPreamble()}
        SELECT
          max(dur) as maxDur
        FROM (
          SELECT
            lead(ts, 1, ts) over (order by ts) - ts as dur
          FROM data
        )
      `);
      const maxDurRow = maxDurQuery.firstRow({
        maxDur: LONG,
      });
      const maxDurNs = maxDurRow.maxDur;

      const displayValueQuery = await this.engine.query(`
        ${this.getSqlPreamble()}
        SELECT
          max(displayValue) as maxDisplayValue,
          min(displayValue) as minDisplayValue
        FROM data
      `);
      const displayValueRow = displayValueQuery.firstRow({
        minDisplayValue: NUM,
        maxDisplayValue: NUM,
      });

      const minDisplayValue = displayValueRow.minDisplayValue;
      const maxDisplayValue = displayValueRow.maxDisplayValue;
      limits = this.limits = {
        minDisplayValue,
        maxDisplayValue,
        maxDurNs,
      };
    }

    if (rawCountersKey.isCoveredBy(this.countersKey)) {
      return;  // We have the data already, no need to re-query.
    }

    const countersKey = rawCountersKey.normalize();
    if (!rawCountersKey.isCoveredBy(countersKey)) {
      throw new Error(`Normalization error ${countersKey.toString()} ${
        rawCountersKey.toString()}`);
    }

    const maybeCachedCounters = this.cache.lookup(countersKey);
    if (maybeCachedCounters) {
      this.countersKey = countersKey;
      this.counters = maybeCachedCounters;
    }

    const bucketNs = countersKey.bucketSize;

    const constraint = constraintsToQuerySuffix({
      filters: [
        `ts >= ${countersKey.start} - ${limits.maxDurNs}`,
        `ts <= ${countersKey.end}`,
        `value is not null`,
      ],
      groupBy: [
        'tsq',
      ],
      orderBy: [
        'tsq',
      ],
    });

    const queryRes = await this.engine.query(`
      ${this.getSqlPreamble()}
      SELECT
        (ts + ${bucketNs / 2n}) / ${bucketNs} * ${bucketNs} as tsq,
        count(value) as count,
        avg(value) as avgValue,
        min(displayValue) as minDisplayValue,
        max(displayValue) as maxDisplayValue,
        value_at_max_ts(ts, displayValue) as lastDisplayValue
      FROM data
      ${constraint}
    `);

    const it = queryRes.iter({
      tsq: LONG,
      count: NUM,
      avgValue: NUM,
      minDisplayValue: NUM,
      maxDisplayValue: NUM,
      lastDisplayValue: NUM,
    });

    const numRows = queryRes.numRows();
    const data: CounterData = {
      timestamps: new BigInt64Array(numRows),
      counts: new Uint32Array(numRows),
      avgValues: new Float64Array(numRows),
      minDisplayValues: new Float64Array(numRows),
      maxDisplayValues: new Float64Array(numRows),
      lastDisplayValues: new Float64Array(numRows),
      displayValueRange: [0, 0],
    };

    let min = 0;
    let max = 0;
    for (let row = 0; it.valid(); it.next(), row++) {
      const ts = Time.fromRaw(it.tsq);
      data.timestamps[row] = ts;
      data.counts[row] = it.count;
      data.avgValues[row] = it.avgValue;
      data.minDisplayValues[row] = it.minDisplayValue;
      data.maxDisplayValues[row] = it.maxDisplayValue;
      data.lastDisplayValues[row] = it.lastDisplayValue;
      min = Math.min(min, it.minDisplayValue);
      max = Math.max(max, it.maxDisplayValue);
    }

    data.displayValueRange = [min, max];

    this.cache.insert(countersKey, data);
    this.counters = data;

    raf.scheduleRedraw();
  }

  get unit(): string {
    return this.getCounterOptions().unit ?? '?';
  }
}
