// 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 {findRef} from '../base/dom_utils';
import {FuzzyFinder} from '../base/fuzzy';
import {assertExists, assertUnreachable} from '../base/logging';
import {undoCommonChatAppReplacements} from '../base/string_utils';
import {
  setDurationPrecision,
  setTimestampFormat,
} from '../core/timestamp_format';
import {raf} from '../core/raf_scheduler';
import {Command} from '../public/command';
import {HotkeyConfig, HotkeyContext} from '../widgets/hotkey_context';
import {HotkeyGlyphs} from '../widgets/hotkey_glyphs';
import {maybeRenderFullscreenModalDialog, showModal} from '../widgets/modal';
import {CookieConsent} from './cookie_consent';
import {toggleHelp} from './help_modal';
import {Omnibox, OmniboxOption} from './omnibox';
import {addQueryResultsTab} from '../public/lib/query_table/query_result_tab';
import {Sidebar} from './sidebar';
import {Topbar} from './topbar';
import {shareTrace} from './trace_share_utils';
import {AggregationsTabs} from './aggregation_tab';
import {OmniboxMode} from '../core/omnibox_manager';
import {PromptOption} from '../public/omnibox';
import {DisposableStack} from '../base/disposable_stack';
import {Spinner} from '../widgets/spinner';
import {TraceImpl} from '../core/trace_impl';
import {AppImpl} from '../core/app_impl';
import {NotesEditorTab} from './notes_panel';
import {NotesListEditor} from './notes_list_editor';
import {getTimeSpanOfSelectionOrVisibleWindow} from '../public/utils';
import {DurationPrecision, TimestampFormat} from '../public/timeline';

const OMNIBOX_INPUT_REF = 'omnibox';

// This wrapper creates a new instance of UiMainPerTrace for each new trace
// loaded (including the case of no trace at the beginning).
export class UiMain implements m.ClassComponent {
  view() {
    const currentTraceId = AppImpl.instance.trace?.engine.engineId ?? '';
    return [m(UiMainPerTrace, {key: currentTraceId})];
  }
}

// This components gets destroyed and recreated every time the current trace
// changes. Note that in the beginning the current trace is undefined.
export class UiMainPerTrace implements m.ClassComponent {
  // NOTE: this should NOT need to be an AsyncDisposableStack. If you feel the
  // need of making it async because you want to clean up SQL resources, that
  // will cause bugs (see comments in oncreate()).
  private trash = new DisposableStack();
  private omniboxInputEl?: HTMLInputElement;
  private recentCommands: string[] = [];
  private trace?: TraceImpl;

  // This function is invoked once per trace.
  constructor() {
    const app = AppImpl.instance;
    const trace = app.trace;
    this.trace = trace;

    // Register global commands (commands that are useful even without a trace
    // loaded).
    const globalCmds: Command[] = [
      {
        id: 'perfetto.OpenCommandPalette',
        name: 'Open command palette',
        callback: () => app.omnibox.setMode(OmniboxMode.Command),
        defaultHotkey: '!Mod+Shift+P',
      },

      {
        id: 'perfetto.ShowHelp',
        name: 'Show help',
        callback: () => toggleHelp(),
        defaultHotkey: '?',
      },
    ];
    globalCmds.forEach((cmd) => {
      this.trash.use(app.commands.registerCommand(cmd));
    });

    // When the UI loads there is no trace. There is no point registering
    // commands or anything in this state as they will be useless.
    if (trace === undefined) return;
    document.title = `${trace.traceInfo.traceTitle || 'Trace'} - Perfetto UI`;
    this.maybeShowJsonWarning();

    // Register the aggregation tabs.
    this.trash.use(new AggregationsTabs(trace));

    // Register the notes manager+editor.
    this.trash.use(trace.tabs.registerDetailsPanel(new NotesEditorTab(trace)));

    this.trash.use(
      trace.tabs.registerTab({
        uri: 'notes.manager',
        isEphemeral: false,
        content: {
          getTitle: () => 'Notes & markers',
          render: () => m(NotesListEditor, {trace}),
        },
      }),
    );

    const 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.Milliseconds, displayName: 'Milliseconds'},
            {key: TimestampFormat.Microseconds, displayName: 'Microseconds'},
            {key: TimestampFormat.TraceNs, displayName: 'Trace nanoseconds'},
            {
              key: TimestampFormat.TraceNsLocale,
              displayName:
                'Trace nanoseconds (with locale-specific formatting)',
            },
          ];
          const promptText = 'Select format...';

          const result = await app.omnibox.prompt(promptText, options);
          if (result === undefined) return;
          setTimestampFormat(result as TimestampFormat);
          raf.scheduleFullRedraw();
        },
      },
      {
        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...';

          const result = await app.omnibox.prompt(promptText, options);
          if (result === undefined) return;
          setDurationPrecision(result as DurationPrecision);
          raf.scheduleFullRedraw();
        },
      },
      {
        id: 'perfetto.TogglePerformanceMetrics',
        name: 'Toggle performance metrics',
        callback: () =>
          (app.perfDebugging.enabled = !app.perfDebugging.enabled),
      },
      {
        id: 'perfetto.ShareTrace',
        name: 'Share trace',
        callback: shareTrace,
      },
      {
        id: 'perfetto.SearchNext',
        name: 'Go to next search result',
        callback: () => {
          trace.search.stepForward();
        },
        defaultHotkey: 'Enter',
      },
      {
        id: 'perfetto.SearchPrev',
        name: 'Go to previous search result',
        callback: () => {
          trace.search.stepBackwards();
        },
        defaultHotkey: 'Shift+Enter',
      },
      {
        id: 'perfetto.RunQuery',
        name: 'Run query',
        callback: () => trace.omnibox.setMode(OmniboxMode.Query),
      },
      {
        id: 'perfetto.Search',
        name: 'Search',
        callback: () => trace.omnibox.setMode(OmniboxMode.Search),
        defaultHotkey: '/',
      },
      {
        id: 'perfetto.CopyTimeWindow',
        name: `Copy selected time window to clipboard`,
        callback: async () => {
          const window = await getTimeSpanOfSelectionOrVisibleWindow(trace);
          const query = `ts >= ${window.start} and ts < ${window.end}`;
          copyToClipboard(query);
        },
      },
      {
        id: 'perfetto.FocusSelection',
        name: 'Focus current selection',
        callback: () => trace.selection.scrollToCurrentSelection(),
        defaultHotkey: 'F',
      },
      {
        id: 'perfetto.Deselect',
        name: 'Deselect',
        callback: () => {
          trace.selection.clear();
        },
        defaultHotkey: 'Escape',
      },
      {
        id: 'perfetto.SetTemporarySpanNote',
        name: 'Set the temporary span note based on the current selection',
        callback: () => {
          const range = trace.selection.findTimeRangeOfSelection();
          if (range) {
            trace.notes.addSpanNote({
              start: range.start,
              end: range.end,
              id: '__temp__',
            });
          }
        },
        defaultHotkey: 'M',
      },
      {
        id: 'perfetto.AddSpanNote',
        name: 'Add a new span note based on the current selection',
        callback: () => {
          const range = trace.selection.findTimeRangeOfSelection();
          if (range) {
            trace.notes.addSpanNote({
              start: range.start,
              end: range.end,
            });
          }
        },
        defaultHotkey: 'Shift+M',
      },
      {
        id: 'perfetto.RemoveSelectedNote',
        name: 'Remove selected note',
        callback: () => {
          const selection = trace.selection.selection;
          if (selection.kind === 'note') {
            trace.notes.removeNote(selection.id);
          }
        },
        defaultHotkey: 'Delete',
      },
      {
        id: 'perfetto.NextFlow',
        name: 'Next flow',
        callback: () => trace.flows.focusOtherFlow('Forward'),
        defaultHotkey: 'Mod+]',
      },
      {
        id: 'perfetto.PrevFlow',
        name: 'Prev flow',
        callback: () => trace.flows.focusOtherFlow('Backward'),
        defaultHotkey: 'Mod+[',
      },
      {
        id: 'perfetto.MoveNextFlow',
        name: 'Move next flow',
        callback: () => trace.flows.moveByFocusedFlow('Forward'),
        defaultHotkey: ']',
      },
      {
        id: 'perfetto.MovePrevFlow',
        name: 'Move prev flow',
        callback: () => trace.flows.moveByFocusedFlow('Backward'),
        defaultHotkey: '[',
      },
      {
        id: 'perfetto.SelectAll',
        name: 'Select all',
        callback: () => {
          // This is a dual state command:
          // - If one ore more tracks are already area selected, expand the time
          //   range to include the entire trace, but keep the selection on just
          //   these tracks.
          // - If nothing is selected, or all selected tracks are entirely
          //   selected, then select the entire trace. This allows double tapping
          //   Ctrl+A to select the entire track, then select the entire trace.
          let tracksToSelect: string[];
          const selection = trace.selection.selection;
          if (selection.kind === 'area') {
            // Something is already selected, let's see if it covers the entire
            // span of the trace or not
            const coversEntireTimeRange =
              trace.traceInfo.start === selection.start &&
              trace.traceInfo.end === selection.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 = selection.trackUris;
            } else {
              // If the entire time range is already covered, update the selection
              // to cover all tracks.
              tracksToSelect = trace.workspace.flatTracks
                .map((t) => t.uri)
                .filter((uri) => uri !== undefined);
            }
          } else {
            // If the current selection is not an area, select all.
            tracksToSelect = trace.workspace.flatTracks
              .map((t) => t.uri)
              .filter((uri) => uri !== undefined);
          }
          const {start, end} = trace.traceInfo;
          trace.selection.selectArea({
            start,
            end,
            trackUris: tracksToSelect,
          });
        },
        defaultHotkey: 'Mod+A',
      },
      {
        id: 'perfetto.ConvertSelectionToArea',
        name: 'Convert the current selection to an area selection',
        callback: () => {
          const selection = trace.selection.selection;
          const range = trace.selection.findTimeRangeOfSelection();
          if (selection.kind === 'track_event' && range) {
            trace.selection.selectArea({
              start: range.start,
              end: range.end,
              trackUris: [selection.trackUri],
            });
          }
        },
        // TODO(stevegolton): Decide on a sensible hotkey.
        // defaultHotkey: 'L',
      },
      {
        id: 'perfetto.ToggleDrawer',
        name: 'Toggle drawer',
        defaultHotkey: 'Q',
        callback: () => trace.tabs.toggleTabPanelVisibility(),
      },
    ];

    // Register each command with the command manager
    cmds.forEach((cmd) => {
      this.trash.use(trace.commands.registerCommand(cmd));
    });
  }

  private renderOmnibox(): m.Children {
    const omnibox = AppImpl.instance.omnibox;
    const omniboxMode = omnibox.mode;
    const statusMessage = omnibox.statusMessage;
    if (statusMessage !== undefined) {
      return m(
        `.omnibox.message-mode`,
        m(`input[readonly][disabled][ref=omnibox]`, {
          value: '',
          placeholder: statusMessage,
        }),
      );
    } else if (omniboxMode === OmniboxMode.Command) {
      return this.renderCommandOmnibox();
    } else if (omniboxMode === OmniboxMode.Prompt) {
      return this.renderPromptOmnibox();
    } else if (omniboxMode === OmniboxMode.Query) {
      return this.renderQueryOmnibox();
    } else if (omniboxMode === OmniboxMode.Search) {
      return this.renderSearchOmnibox();
    } else {
      assertUnreachable(omniboxMode);
    }
  }

  renderPromptOmnibox(): m.Children {
    const omnibox = AppImpl.instance.omnibox;
    const prompt = assertExists(omnibox.pendingPrompt);

    let options: OmniboxOption[] | undefined = undefined;

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

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

  renderCommandOmnibox(): m.Children {
    // Fuzzy-filter commands by the filter string.
    const {commands, omnibox} = AppImpl.instance;
    const filteredCmds = commands.fuzzyFilterCommands(omnibox.text);

    // 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: omnibox.text,
      placeholder: 'Filter commands...',
      inputRef: OMNIBOX_INPUT_REF,
      extraClasses: 'command-mode',
      options,
      closeOnSubmit: true,
      closeOnOutsideClick: true,
      selectedOptionIndex: omnibox.selectionIndex,
      onSelectedOptionChanged: (index) => {
        omnibox.setSelectionIndex(index);
        raf.scheduleFullRedraw();
      },
      onInput: (value) => {
        omnibox.setText(value);
        omnibox.setSelectionIndex(0);
        raf.scheduleFullRedraw();
      },
      onClose: () => {
        if (this.omniboxInputEl) {
          this.omniboxInputEl.blur();
        }
        omnibox.reset();
      },
      onSubmit: (key: string) => {
        this.addRecentCommand(key);
        commands.runCommand(key);
      },
      onGoBack: () => {
        omnibox.reset();
      },
    });
  }

  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: AppImpl.instance.omnibox.text,
      placeholder: ph,
      inputRef: OMNIBOX_INPUT_REF,
      extraClasses: 'query-mode',

      onInput: (value) => {
        AppImpl.instance.omnibox.setText(value);
        raf.scheduleFullRedraw();
      },
      onSubmit: (query, alt) => {
        const config = {
          query: undoCommonChatAppReplacements(query),
          title: alt ? 'Pinned query' : 'Omnibox query',
        };
        const tag = alt ? undefined : 'omnibox_query';
        const trace = AppImpl.instance.trace;
        if (trace === undefined) return; // No trace loaded
        addQueryResultsTab(trace, config, tag);
      },
      onClose: () => {
        AppImpl.instance.omnibox.setText('');
        if (this.omniboxInputEl) {
          this.omniboxInputEl.blur();
        }
        AppImpl.instance.omnibox.reset();
        raf.scheduleFullRedraw();
      },
      onGoBack: () => {
        AppImpl.instance.omnibox.reset();
      },
    });
  }

  renderSearchOmnibox(): m.Children {
    return m(Omnibox, {
      value: AppImpl.instance.omnibox.text,
      placeholder: "Search or type '>' for commands or ':' for SQL mode",
      inputRef: OMNIBOX_INPUT_REF,
      onInput: (value, _prev) => {
        if (value === '>') {
          AppImpl.instance.omnibox.setMode(OmniboxMode.Command);
          return;
        } else if (value === ':') {
          AppImpl.instance.omnibox.setMode(OmniboxMode.Query);
          return;
        }
        AppImpl.instance.omnibox.setText(value);
        if (this.trace === undefined) return; // No trace loaded.
        if (value.length >= 4) {
          this.trace.search.search(value);
        } else {
          this.trace.search.reset();
        }
      },
      onClose: () => {
        if (this.omniboxInputEl) {
          this.omniboxInputEl.blur();
        }
      },
      onSubmit: (value, _mod, shift) => {
        if (this.trace === undefined) return; // No trace loaded.
        this.trace.search.search(value);
        if (shift) {
          this.trace.search.stepBackwards();
        } else {
          this.trace.search.stepForward();
        }
        if (this.omniboxInputEl) {
          this.omniboxInputEl.blur();
        }
      },
      rightContent: this.renderStepThrough(),
    });
  }

  private renderStepThrough() {
    const children = [];
    const results = this.trace?.search.searchResults;
    if (this.trace?.search.searchInProgress) {
      children.push(m('.current', m(Spinner)));
    } else if (results !== undefined) {
      const searchMgr = assertExists(this.trace).search;
      const index = searchMgr.resultIndex;
      const total = results.totalResults ?? 0;
      children.push(
        m('.current', `${total === 0 ? '0 / 0' : `${index + 1} / ${total}`}`),
        m(
          'button',
          {
            onclick: () => searchMgr.stepBackwards(),
          },
          m('i.material-icons.left', 'keyboard_arrow_left'),
        ),
        m(
          'button',
          {
            onclick: () => searchMgr.stepForward(),
          },
          m('i.material-icons.right', 'keyboard_arrow_right'),
        ),
      );
    }
    return m('.stepthrough', children);
  }

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

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

    return m(
      HotkeyContext,
      {hotkeys},
      m(
        'main',
        m(Sidebar, {trace: this.trace}),
        m(Topbar, {
          omnibox: this.renderOmnibox(),
          trace: this.trace,
        }),
        app.pages.renderPageForCurrentRoute(app.trace),
        m(CookieConsent),
        maybeRenderFullscreenModalDialog(),
        app.perfDebugging.renderPerfStats(),
      ),
    );
  }

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

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

    // NOTE: if this becomes ever an asyncDispose(), then the promise needs to
    // be returned to onbeforeremove, so mithril delays the removal until
    // the promise is resolved, but then also the UiMain wrapper needs to be
    // more complex to linearize the destruction of the old instane with the
    // creation of the new one, without overlaps.
    // However, we should not add disposables that issue cleanup queries on the
    // Engine. Doing so is: (1) useless: we throw away the whole wasm instance
    // on each trace load, so what's the point of deleting tables from a TP
    // instance that is going to be destroyed?; (2) harmful: we don't have
    // precise linearization with the wasm teardown, so we might end up awaiting
    // forever for the asyncDispose() because the query will never run.
    this.trash.dispose();
  }

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

  private maybeFocusOmnibar() {
    if (AppImpl.instance.omnibox.focusOmniboxNextRender) {
      const omniboxEl = this.omniboxInputEl;
      if (omniboxEl) {
        omniboxEl.focus();
        if (AppImpl.instance.omnibox.pendingCursorPlacement === undefined) {
          omniboxEl.select();
        } else {
          omniboxEl.setSelectionRange(
            AppImpl.instance.omnibox.pendingCursorPlacement,
            AppImpl.instance.omnibox.pendingCursorPlacement,
          );
        }
      }
      AppImpl.instance.omnibox.clearFocusFlag();
    }
  }

  private async maybeShowJsonWarning() {
    // Show warning if the trace is in JSON format.
    const isJsonTrace = this.trace?.traceInfo.traceType === 'json';
    const SHOWN_JSON_WARNING_KEY = 'shownJsonWarning';

    if (
      !isJsonTrace ||
      window.localStorage.getItem(SHOWN_JSON_WARNING_KEY) === 'true' ||
      AppImpl.instance.embeddedMode
    ) {
      // When in embedded mode, the host app will control which trace format
      // it passes to Perfetto, so we don't need to show this warning.
      return;
    }

    // Save that the warning has been shown. Value is irrelevant since only
    // the presence of key is going to be checked.
    window.localStorage.setItem(SHOWN_JSON_WARNING_KEY, 'true');

    showModal({
      title: 'Warning',
      content: m(
        'div',
        m(
          'span',
          'Perfetto UI features are limited for JSON traces. ',
          'We recommend recording ',
          m(
            'a',
            {href: 'https://perfetto.dev/docs/quickstart/chrome-tracing'},
            'proto-format traces',
          ),
          ' from Chrome.',
        ),
        m('br'),
      ),
      buttons: [],
    });
  }
}
