// 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 {copyToClipboard} from '../base/clipboard';
import {Trash} from '../base/disposable';
import {findRef} from '../base/dom_utils';
import {FuzzyFinder} from '../base/fuzzy';
import {assertExists} from '../base/logging';
import {undoCommonChatAppReplacements} from '../base/string_utils';
import {duration, Span, Time, time, TimeSpan} from '../base/time';
import {Actions} from '../common/actions';
import {getLegacySelection} from '../common/state';
import {runQuery} from '../common/queries';
import {
  DurationPrecision,
  setDurationPrecision,
  setTimestampFormat,
  TimestampFormat,
} from '../core/timestamp_format';
import {raf} from '../core/raf_scheduler';
import {Command} from '../public';
import {EngineProxy} from '../trace_processor/engine';
import {THREAD_STATE_TRACK_KIND} from '../tracks/thread_state';
import {HotkeyConfig, HotkeyContext} from '../widgets/hotkey_context';
import {HotkeyGlyphs} from '../widgets/hotkey_glyphs';
import {maybeRenderFullscreenModalDialog} from '../widgets/modal';

import {onClickCopy} from './clipboard';
import {CookieConsent} from './cookie_consent';
import {globals} from './globals';
import {toggleHelp} from './help_modal';
import {Notes} from './notes';
import {Omnibox, OmniboxOption} from './omnibox';
import {addQueryResultsTab} from './query_result_tab';
import {verticalScrollToTrack} from './scroll_helper';
import {executeSearch} from './search_handler';
import {Sidebar} from './sidebar';
import {Utid} from './sql_types';
import {getThreadInfo} from './thread_and_process_info';
import {Topbar} from './topbar';
import {shareTrace} from './trace_attrs';
import {addDebugSliceTrack} from './debug_tracks';
import {AggregationsTabs} from './aggregation_tab';
import {addSqlTableTab} from './sql_table/tab';
import {SqlTables} from './sql_table/well_known_tables';
import {
  findCurrentSelection,
  focusOtherFlow,
  lockSliceSpan,
  moveByFocusedFlow,
} from './keyboard_event_handler';

function renderPermalink(): m.Children {
  const permalink = globals.state.permalink;
  if (!permalink.requestId || !permalink.hash) return null;
  const url = `${self.location.origin}/#!/?s=${permalink.hash}`;
  const linkProps = {title: 'Click to copy the URL', onclick: onClickCopy(url)};

  return m('.alert-permalink', [
    m('div', 'Permalink: ', m(`a[href=${url}]`, linkProps, url)),
    m(
      'button',
      {
        onclick: () => globals.dispatch(Actions.clearPermalink({})),
      },
      m('i.material-icons.disallow-selection', 'close'),
    ),
  ]);
}

class Alerts implements m.ClassComponent {
  view() {
    return m('.alerts', renderPermalink());
  }
}

interface PromptOption {
  key: string;
  displayName: string;
}

interface Prompt {
  text: string;
  options?: PromptOption[];
  resolve(result: string): void;
  reject(): void;
}

enum OmniboxMode {
  Search,
  Query,
  Command,
  Prompt,
}

const criticalPathSliceColumns = {
  ts: 'ts',
  dur: 'dur',
  name: 'name',
};
const criticalPathsliceColumnNames = [
  'id',
  'utid',
  'ts',
  'dur',
  'name',
  'table_name',
];

const criticalPathsliceLiteColumns = {
  ts: 'ts',
  dur: 'dur',
  name: 'thread_name',
};
const criticalPathsliceLiteColumnNames = [
  'id',
  'utid',
  'ts',
  'dur',
  'thread_name',
  'process_name',
  'table_name',
];

export class App implements m.ClassComponent {
  private trash = new Trash();

  private omniboxMode: OmniboxMode = OmniboxMode.Search;
  private omniboxText = '';
  private queryText = '';
  private omniboxSelectionIndex = 0;
  private focusOmniboxNextRender = false;
  private pendingCursorPlacement = -1;
  private pendingPrompt?: Prompt;
  static readonly OMNIBOX_INPUT_REF = 'omnibox';
  private omniboxInputEl?: HTMLInputElement;
  private recentCommands: string[] = [];

  constructor() {
    this.trash.add(new Notes());
    this.trash.add(new AggregationsTabs());
  }

  private getEngine(): EngineProxy | undefined {
    const engineId = globals.getCurrentEngine()?.id;
    if (engineId === undefined) {
      return undefined;
    }
    const engine = globals.engines.get(engineId)?.getProxy('QueryPage');
    return engine;
  }

  private enterCommandMode(): void {
    this.omniboxMode = OmniboxMode.Command;
    this.resetOmnibox();
    this.rejectPendingPrompt();
    this.focusOmniboxNextRender = true;

    raf.scheduleFullRedraw();
  }

  private enterQueryMode(): void {
    this.omniboxMode = OmniboxMode.Query;
    this.resetOmnibox();
    this.rejectPendingPrompt();
    this.focusOmniboxNextRender = true;

    raf.scheduleFullRedraw();
  }

  private enterSearchMode(focusOmnibox: boolean): void {
    this.omniboxMode = OmniboxMode.Search;
    this.resetOmnibox();
    this.rejectPendingPrompt();

    if (focusOmnibox) {
      this.focusOmniboxNextRender = true;
    }

    globals.dispatch(Actions.setOmniboxMode({mode: 'SEARCH'}));

    raf.scheduleFullRedraw();
  }

  // Start a prompt. If options are supplied, the user must pick one from the
  // list, otherwise the input is free-form text.
  private prompt(text: string, options?: PromptOption[]): Promise<string> {
    this.omniboxMode = OmniboxMode.Prompt;
    this.resetOmnibox();
    this.rejectPendingPrompt();

    const promise = new Promise<string>((resolve, reject) => {
      this.pendingPrompt = {
        text,
        options,
        resolve,
        reject,
      };
    });

    this.focusOmniboxNextRender = true;
    raf.scheduleFullRedraw();

    return promise;
  }

  // Resolve the pending prompt with a value to return to the prompter.
  private resolvePrompt(value: string): void {
    if (this.pendingPrompt) {
      this.pendingPrompt.resolve(value);
      this.pendingPrompt = undefined;
    }
    this.enterSearchMode(false);
  }

  // Reject the prompt outright. Doing this will force the owner of the prompt
  // promise to catch, so only do this when things go seriously wrong.
  // Use |resolvePrompt(null)| to indicate cancellation.
  private rejectPrompt(): void {
    if (this.pendingPrompt) {
      this.pendingPrompt.reject();
      this.pendingPrompt = undefined;
    }
    this.enterSearchMode(false);
  }

  private getFirstUtidOfSelectionOrVisibleWindow(): number {
    const selection = getLegacySelection(globals.state);
    if (selection && selection.kind === 'AREA') {
      const selectedArea = globals.state.areas[selection.areaId];
      const firstThreadStateTrack = selectedArea.tracks.find((trackId) => {
        return globals.state.tracks[trackId];
      });

      if (firstThreadStateTrack) {
        const trackInfo = globals.state.tracks[firstThreadStateTrack];
        const trackDesc = globals.trackManager.resolveTrackInfo(trackInfo.uri);
        if (
          trackDesc?.kind === THREAD_STATE_TRACK_KIND &&
          trackDesc?.utid !== undefined
        ) {
          return trackDesc?.utid;
        }
      }
    }

    return 0;
  }

  private cmds: Command[] = [
    {
      id: 'perfetto.SetTimestampFormat',
      name: 'Set timestamp and duration format',
      callback: async () => {
        const options: PromptOption[] = [
          {key: TimestampFormat.Timecode, displayName: 'Timecode'},
          {key: TimestampFormat.UTC, displayName: 'Realtime (UTC)'},
          {
            key: TimestampFormat.TraceTz,
            displayName: 'Realtime (Trace TZ)',
          },
          {key: TimestampFormat.Seconds, displayName: 'Seconds'},
          {key: TimestampFormat.Raw, displayName: 'Raw'},
          {
            key: TimestampFormat.RawLocale,
            displayName: 'Raw (with locale-specific formatting)',
          },
        ];
        const promptText = 'Select format...';

        try {
          const result = await this.prompt(promptText, options);
          setTimestampFormat(result as TimestampFormat);
          raf.scheduleFullRedraw();
        } catch {
          // Prompt was probably cancelled - do nothing.
        }
      },
    },
    {
      id: 'perfetto.SetDurationPrecision',
      name: 'Set duration precision',
      callback: async () => {
        const options: PromptOption[] = [
          {key: DurationPrecision.Full, displayName: 'Full'},
          {
            key: DurationPrecision.HumanReadable,
            displayName: 'Human readable',
          },
        ];
        const promptText = 'Select duration precision mode...';

        try {
          const result = await this.prompt(promptText, options);
          setDurationPrecision(result as DurationPrecision);
          raf.scheduleFullRedraw();
        } catch {
          // Prompt was probably cancelled - do nothing.
        }
      },
    },
    {
      id: 'perfetto.CriticalPathLite',
      name: `Critical path lite`,
      callback: async () => {
        const trackUtid = this.getFirstUtidOfSelectionOrVisibleWindow();
        const window = getTimeSpanOfSelectionOrVisibleWindow();
        const engine = this.getEngine();

        if (engine !== undefined && trackUtid != 0) {
          await runQuery(
            `INCLUDE PERFETTO MODULE sched.thread_executing_span;`,
            engine,
          );
          await addDebugSliceTrack(
            engine,
            {
              sqlSource: `
                   SELECT
                      cr.id,
                      cr.utid,
                      cr.ts,
                      cr.dur,
                      thread.name AS thread_name,
                      process.name AS process_name,
                      'thread_state' AS table_name
                    FROM
                      _thread_executing_span_critical_path(
                          ${trackUtid},
                          ${window.start},
                          ${window.end} - ${window.start}) cr
                    JOIN thread USING(utid)
                    JOIN process USING(upid)
                  `,
              columns: criticalPathsliceLiteColumnNames,
            },
            (await getThreadInfo(engine, trackUtid as Utid)).name ??
              '<thread name>',
            criticalPathsliceLiteColumns,
            criticalPathsliceLiteColumnNames,
          );
        }
      },
    },
    {
      id: 'perfetto.CriticalPath',
      name: `Critical path`,
      callback: async () => {
        const trackUtid = this.getFirstUtidOfSelectionOrVisibleWindow();
        const window = getTimeSpanOfSelectionOrVisibleWindow();
        const engine = this.getEngine();

        if (engine !== undefined && trackUtid != 0) {
          await runQuery(
            `INCLUDE PERFETTO MODULE sched.thread_executing_span_with_slice;`,
            engine,
          );
          await addDebugSliceTrack(
            engine,
            {
              sqlSource: `
                        SELECT cr.id, cr.utid, cr.ts, cr.dur, cr.name, cr.table_name
                        FROM
                        _critical_path_stack(
                          ${trackUtid},
                          ${window.start},
                          ${window.end} - ${window.start}, 1, 1, 1, 1) cr WHERE name IS NOT NULL
                  `,
              columns: criticalPathsliceColumnNames,
            },
            (await getThreadInfo(engine, trackUtid as Utid)).name ??
              '<thread name>',
            criticalPathSliceColumns,
            criticalPathsliceColumnNames,
          );
        }
      },
    },
    {
      id: 'perfetto.CriticalPathPprof',
      name: `Critical path pprof`,
      callback: () => {
        const trackUtid = this.getFirstUtidOfSelectionOrVisibleWindow();
        const window = getTimeSpanOfSelectionOrVisibleWindow();
        const engine = this.getEngine();

        if (engine !== undefined && trackUtid != 0) {
          addQueryResultsTab({
            query: `INCLUDE PERFETTO MODULE sched.thread_executing_span_with_slice;
                   SELECT *
                      FROM
                        _thread_executing_span_critical_path_graph(
                        "criical_path",
                         ${trackUtid},
                         ${window.start},
                         ${window.end} - ${window.start}) cr`,
            title: 'Critical path',
          });
        }
      },
    },
    {
      id: 'perfetto.ShowSliceTable',
      name: 'Open new slice table tab',
      callback: () => {
        addSqlTableTab({
          table: SqlTables.slice,
          displayName: 'slice',
        });
      },
    },
    {
      id: 'perfetto.TogglePerformanceMetrics',
      name: 'Toggle performance metrics',
      callback: () => {
        globals.dispatch(Actions.togglePerfDebug({}));
      },
    },
    {
      id: 'perfetto.ShareTrace',
      name: 'Share trace',
      callback: shareTrace,
    },
    {
      id: 'perfetto.SearchNext',
      name: 'Go to next search result',
      callback: () => {
        executeSearch();
      },
      defaultHotkey: 'Enter',
    },
    {
      id: 'perfetto.SearchPrev',
      name: 'Go to previous search result',
      callback: () => {
        executeSearch(true);
      },
      defaultHotkey: 'Shift+Enter',
    },
    {
      id: 'perfetto.OpenCommandPalette',
      name: 'Open command palette',
      callback: () => this.enterCommandMode(),
      defaultHotkey: '!Mod+Shift+P',
    },
    {
      id: 'perfetto.RunQuery',
      name: 'Run query',
      callback: () => this.enterQueryMode(),
      defaultHotkey: '!Mod+O',
    },
    {
      id: 'perfetto.Search',
      name: 'Search',
      callback: () => this.enterSearchMode(true),
      defaultHotkey: '!Mod+S',
    },
    {
      id: 'perfetto.ShowHelp',
      name: 'Show help',
      callback: () => toggleHelp(),
      defaultHotkey: '?',
    },
    {
      id: 'perfetto.RunQueryInSelectedTimeWindow',
      name: `Run query in selected time window`,
      callback: () => {
        const window = getTimeSpanOfSelectionOrVisibleWindow();
        this.enterQueryMode();
        this.queryText = `select  where ts >= ${window.start} and ts < ${window.end}`;
        this.pendingCursorPlacement = 7;
      },
    },
    {
      id: 'perfetto.CopyTimeWindow',
      name: `Copy selected time window to clipboard`,
      callback: () => {
        const window = getTimeSpanOfSelectionOrVisibleWindow();
        const query = `ts >= ${window.start} and ts < ${window.end}`;
        copyToClipboard(query);
      },
    },
    {
      // Selects & reveals the first track on the timeline with a given URI.
      id: 'perfetto.FindTrack',
      name: 'Find track by URI',
      callback: async () => {
        const tracks = globals.trackManager.getAllTracks();
        const options = tracks.map(({uri}): PromptOption => {
          return {key: uri, displayName: uri};
        });

        // Sort tracks in a natural sort order
        const collator = new Intl.Collator('en', {
          numeric: true,
          sensitivity: 'base',
        });
        const sortedOptions = options.sort((a, b) => {
          return collator.compare(a.displayName, b.displayName);
        });

        try {
          const selectedUri = await this.prompt(
            'Choose a track...',
            sortedOptions,
          );

          // Find the first track with this URI
          const firstTrack = Object.values(globals.state.tracks).find(
            ({uri}) => uri === selectedUri,
          );
          if (firstTrack) {
            console.log(firstTrack);
            verticalScrollToTrack(firstTrack.key, true);
            const traceTime = globals.stateTraceTimeTP();
            globals.makeSelection(
              Actions.selectArea({
                area: {
                  start: traceTime.start,
                  end: traceTime.end,
                  tracks: [firstTrack.key],
                },
              }),
            );
          } else {
            alert(`No tracks with uri ${selectedUri} on the timeline`);
          }
        } catch {
          // Prompt was probably cancelled - do nothing.
        }
      },
    },
    {
      id: 'perfetto.FocusSelection',
      name: 'Focus current selection',
      callback: () => findCurrentSelection(),
      defaultHotkey: 'F',
    },
    {
      id: 'perfetto.Deselect',
      name: 'Deselect',
      callback: () => {
        globals.timeline.deselectArea();
        globals.clearSelection();
        globals.dispatch(Actions.removeNote({id: '0'}));
      },
      defaultHotkey: 'Escape',
    },
    {
      id: 'perfetto.MarkArea',
      name: 'Mark area',
      callback: () => {
        const selection = getLegacySelection(globals.state);
        if (selection && selection.kind === 'AREA') {
          globals.dispatch(Actions.toggleMarkCurrentArea({persistent: false}));
        } else if (selection) {
          lockSliceSpan(false);
        }
      },
      defaultHotkey: 'M',
    },
    {
      id: 'perfetto.MarkAreaPersistent',
      name: 'Mark area (persistent)',
      callback: () => {
        const selection = getLegacySelection(globals.state);
        if (selection && selection.kind === 'AREA') {
          globals.dispatch(Actions.toggleMarkCurrentArea({persistent: true}));
        } else if (selection) {
          lockSliceSpan(true);
        }
      },
      defaultHotkey: 'Shift+M',
    },
    {
      id: 'perfetto.NextFlow',
      name: 'Next flow',
      callback: () => focusOtherFlow('Forward'),
      defaultHotkey: 'Mod+]',
    },
    {
      id: 'perfetto.PrevFlow',
      name: 'Prev flow',
      callback: () => focusOtherFlow('Backward'),
      defaultHotkey: 'Mod+[',
    },
    {
      id: 'perfetto.MoveNextFlow',
      name: 'Move next flow',
      callback: () => moveByFocusedFlow('Forward'),
      defaultHotkey: ']',
    },
    {
      id: 'perfetto.MovePrevFlow',
      name: 'Move prev flow',
      callback: () => moveByFocusedFlow('Backward'),
      defaultHotkey: '[',
    },
    {
      id: 'perfetto.SelectAll',
      name: 'Select all',
      callback: () => {
        let tracksToSelect: string[] = [];

        const selection = getLegacySelection(globals.state);
        if (selection !== null && selection.kind === 'AREA') {
          const area = globals.state.areas[selection.areaId];
          const coversEntireTimeRange =
            globals.state.traceTime.start === area.start &&
            globals.state.traceTime.end === area.end;
          if (!coversEntireTimeRange) {
            // If the current selection is an area which does not cover the
            // entire time range, preserve the list of selected tracks and
            // expand the time range.
            tracksToSelect = area.tracks;
          } else {
            // If the entire time range is already covered, update the selection
            // to cover all tracks.
            tracksToSelect = Object.keys(globals.state.tracks);
          }
        } else {
          // If the current selection is not an area, select all.
          tracksToSelect = Object.keys(globals.state.tracks);
        }
        const {start, end} = globals.state.traceTime;
        globals.dispatch(
          Actions.selectArea({
            area: {
              start,
              end,
              tracks: tracksToSelect,
            },
          }),
        );
      },
      defaultHotkey: 'Mod+A',
    },
  ];

  commands() {
    return this.cmds;
  }

  private rejectPendingPrompt() {
    if (this.pendingPrompt) {
      this.pendingPrompt.reject();
      this.pendingPrompt = undefined;
    }
  }

  private resetOmnibox() {
    this.omniboxText = '';
    this.omniboxSelectionIndex = 0;
  }

  private renderOmnibox(): m.Children {
    const msgTTL = globals.state.status.timestamp + 1 - Date.now() / 1e3;
    const engineIsBusy =
      globals.state.engine !== undefined && !globals.state.engine.ready;

    if (msgTTL > 0 || engineIsBusy) {
      setTimeout(() => raf.scheduleFullRedraw(), msgTTL * 1000);
      return m(
        `.omnibox.message-mode`,
        m(`input[readonly][disabled][ref=omnibox]`, {
          value: '',
          placeholder: globals.state.status.msg,
        }),
      );
    }

    if (this.omniboxMode === OmniboxMode.Command) {
      return this.renderCommandOmnibox();
    } else if (this.omniboxMode === OmniboxMode.Prompt) {
      return this.renderPromptOmnibox();
    } else if (this.omniboxMode === OmniboxMode.Query) {
      return this.renderQueryOmnibox();
    } else if (this.omniboxMode === OmniboxMode.Search) {
      return this.renderSearchOmnibox();
    } else {
      const x: never = this.omniboxMode;
      throw new Error(`Unhandled omnibox mode ${x}`);
    }
  }

  renderPromptOmnibox(): m.Children {
    const prompt = assertExists(this.pendingPrompt);

    let options: OmniboxOption[] | undefined = undefined;

    if (prompt.options) {
      const fuzzy = new FuzzyFinder(
        prompt.options,
        ({displayName}) => displayName,
      );
      const result = fuzzy.find(this.omniboxText);
      options = result.map((result) => {
        return {
          key: result.item.key,
          displayName: result.segments,
        };
      });
    }

    return m(Omnibox, {
      value: this.omniboxText,
      placeholder: prompt.text,
      inputRef: App.OMNIBOX_INPUT_REF,
      extraClasses: 'prompt-mode',
      closeOnOutsideClick: true,
      options,
      selectedOptionIndex: this.omniboxSelectionIndex,
      onSelectedOptionChanged: (index) => {
        this.omniboxSelectionIndex = index;
        raf.scheduleFullRedraw();
      },
      onInput: (value) => {
        this.omniboxText = value;
        this.omniboxSelectionIndex = 0;
        raf.scheduleFullRedraw();
      },
      onSubmit: (value, _alt) => {
        this.resolvePrompt(value);
      },
      onClose: () => {
        this.rejectPrompt();
      },
    });
  }

  renderCommandOmnibox(): m.Children {
    const cmdMgr = globals.commandManager;

    // Fuzzy-filter commands by the filter string.
    const filteredCmds = cmdMgr.fuzzyFilterCommands(this.omniboxText);

    // Create an array of commands with attached heuristics from the recent
    // command register.
    const commandsWithHeuristics = filteredCmds.map((cmd) => {
      return {
        recentsIndex: this.recentCommands.findIndex((id) => id === cmd.id),
        cmd,
      };
    });

    // Sort by recentsIndex then by alphabetical order
    const sorted = commandsWithHeuristics.sort((a, b) => {
      if (b.recentsIndex === a.recentsIndex) {
        return a.cmd.name.localeCompare(b.cmd.name);
      } else {
        return b.recentsIndex - a.recentsIndex;
      }
    });

    const options = sorted.map(({recentsIndex, cmd}): OmniboxOption => {
      const {segments, id, defaultHotkey} = cmd;
      return {
        key: id,
        displayName: segments,
        tag: recentsIndex !== -1 ? 'recently used' : undefined,
        rightContent: defaultHotkey && m(HotkeyGlyphs, {hotkey: defaultHotkey}),
      };
    });

    return m(Omnibox, {
      value: this.omniboxText,
      placeholder: 'Filter commands...',
      inputRef: App.OMNIBOX_INPUT_REF,
      extraClasses: 'command-mode',
      options,
      closeOnSubmit: true,
      closeOnOutsideClick: true,
      selectedOptionIndex: this.omniboxSelectionIndex,
      onSelectedOptionChanged: (index) => {
        this.omniboxSelectionIndex = index;
        raf.scheduleFullRedraw();
      },
      onInput: (value) => {
        this.omniboxText = value;
        this.omniboxSelectionIndex = 0;
        raf.scheduleFullRedraw();
      },
      onClose: () => {
        if (this.omniboxInputEl) {
          this.omniboxInputEl.blur();
        }
        this.enterSearchMode(false);
        raf.scheduleFullRedraw();
      },
      onSubmit: (key: string) => {
        this.addRecentCommand(key);
        cmdMgr.runCommand(key);
      },
      onGoBack: () => {
        this.enterSearchMode(false);
      },
    });
  }

  private addRecentCommand(id: string): void {
    this.recentCommands = this.recentCommands.filter((x) => x !== id);
    this.recentCommands.push(id);
    while (this.recentCommands.length > 6) {
      this.recentCommands.shift();
    }
  }

  renderQueryOmnibox(): m.Children {
    const ph = 'e.g. select * from sched left join thread using(utid) limit 10';
    return m(Omnibox, {
      value: this.queryText,
      placeholder: ph,
      inputRef: App.OMNIBOX_INPUT_REF,
      extraClasses: 'query-mode',

      onInput: (value) => {
        this.queryText = value;
        raf.scheduleFullRedraw();
      },
      onSubmit: (query, alt) => {
        const config = {
          query: undoCommonChatAppReplacements(query),
          title: alt ? 'Pinned query' : 'Omnibox query',
        };
        const tag = alt ? undefined : 'omnibox_query';
        addQueryResultsTab(config, tag);
      },
      onClose: () => {
        this.queryText = '';
        if (this.omniboxInputEl) {
          this.omniboxInputEl.blur();
        }
        this.enterSearchMode(false);
        raf.scheduleFullRedraw();
      },
      onGoBack: () => {
        this.enterSearchMode(false);
      },
    });
  }

  renderSearchOmnibox(): m.Children {
    const omniboxState = globals.state.omniboxState;
    const displayStepThrough =
      omniboxState.omnibox.length >= 4 || omniboxState.force;

    return m(Omnibox, {
      value: globals.state.omniboxState.omnibox,
      placeholder: "Search or type '>' for commands or ':' for SQL mode",
      inputRef: App.OMNIBOX_INPUT_REF,
      onInput: (value, prev) => {
        if (prev === '') {
          if (value === '>') {
            this.enterCommandMode();
            return;
          } else if (value === ':') {
            this.enterQueryMode();
            return;
          }
        }
        globals.dispatch(Actions.setOmnibox({omnibox: value, mode: 'SEARCH'}));
      },
      onClose: () => {
        if (this.omniboxInputEl) {
          this.omniboxInputEl.blur();
        }
      },
      onSubmit: (value, _mod, shift) => {
        executeSearch(shift);
        globals.dispatch(
          Actions.setOmnibox({omnibox: value, mode: 'SEARCH', force: true}),
        );
        if (this.omniboxInputEl) {
          this.omniboxInputEl.blur();
        }
      },
      rightContent: displayStepThrough && this.renderStepThrough(),
    });
  }

  private renderStepThrough() {
    return m(
      '.stepthrough',
      m(
        '.current',
        `${
          globals.currentSearchResults.totalResults === 0
            ? '0 / 0'
            : `${globals.state.searchIndex + 1} / ${
                globals.currentSearchResults.totalResults
              }`
        }`,
      ),
      m(
        'button',
        {
          onclick: () => {
            executeSearch(true /* reverse direction */);
          },
        },
        m('i.material-icons.left', 'keyboard_arrow_left'),
      ),
      m(
        'button',
        {
          onclick: () => {
            executeSearch();
          },
        },
        m('i.material-icons.right', 'keyboard_arrow_right'),
      ),
    );
  }

  view({children}: m.Vnode): m.Children {
    const hotkeys: HotkeyConfig[] = [];
    const commands = globals.commandManager.commands;
    for (const {id, defaultHotkey} of commands) {
      if (defaultHotkey) {
        hotkeys.push({
          callback: () => {
            globals.commandManager.runCommand(id);
          },
          hotkey: defaultHotkey,
        });
      }
    }

    return m(
      HotkeyContext,
      {hotkeys},
      m(
        'main',
        m(Sidebar),
        m(Topbar, {
          omnibox: this.renderOmnibox(),
        }),
        m(Alerts),
        children,
        m(CookieConsent),
        maybeRenderFullscreenModalDialog(),
        globals.state.perfDebug && m('.perf-stats'),
      ),
    );
  }

  oncreate({dom}: m.VnodeDOM) {
    this.updateOmniboxInputRef(dom);
    this.maybeFocusOmnibar();

    // Register each command with the command manager
    this.cmds.forEach((cmd) => {
      const dispose = globals.commandManager.registerCommand(cmd);
      this.trash.add(dispose);
    });
  }

  onupdate({dom}: m.VnodeDOM) {
    this.updateOmniboxInputRef(dom);
    this.maybeFocusOmnibar();
  }

  onremove(_: m.VnodeDOM) {
    this.trash.dispose();
    this.omniboxInputEl = undefined;
  }

  private updateOmniboxInputRef(dom: Element): void {
    const el = findRef(dom, App.OMNIBOX_INPUT_REF);
    if (el && el instanceof HTMLInputElement) {
      this.omniboxInputEl = el;
    }
  }

  private maybeFocusOmnibar() {
    if (this.focusOmniboxNextRender) {
      const omniboxEl = this.omniboxInputEl;
      if (omniboxEl) {
        omniboxEl.focus();
        if (this.pendingCursorPlacement === -1) {
          omniboxEl.select();
        } else {
          omniboxEl.setSelectionRange(
            this.pendingCursorPlacement,
            this.pendingCursorPlacement,
          );
          this.pendingCursorPlacement = -1;
        }
      }
      this.focusOmniboxNextRender = false;
    }
  }
}

// Returns the time span of the current selection, or the visible window if
// there is no current selection.
function getTimeSpanOfSelectionOrVisibleWindow(): Span<time, duration> {
  const range = globals.findTimeRangeOfSelection();
  if (range.end !== Time.INVALID && range.start !== Time.INVALID) {
    return new TimeSpan(range.start, range.end);
  } else {
    return globals.stateVisibleTime();
  }
}
