// Copyright (C) 2018 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 {assertExists, assertTrue} from '../base/logging';
import {isString} from '../base/object_utils';
import {Actions} from '../common/actions';
import {getCurrentChannel} from '../common/channels';
import {TRACE_SUFFIX} from '../common/constants';
import {ConversionJobStatus} from '../common/conversion_jobs';
import {
  disableMetatracingAndGetTrace,
  enableMetatracing,
  isMetatracingEnabled,
} from '../common/metatracing';
import {EngineMode} from '../common/state';
import {featureFlags} from '../core/feature_flags';
import {raf} from '../core/raf_scheduler';
import {SCM_REVISION, VERSION} from '../gen/perfetto_version';
import {Engine} from '../trace_processor/engine';
import {showModal} from '../widgets/modal';

import {Animation} from './animation';
import {downloadData, downloadUrl} from './download_utils';
import {globals} from './globals';
import {toggleHelp} from './help_modal';
import {
  isLegacyTrace,
  openFileWithLegacyTraceViewer,
} from './legacy_trace_viewer';
import {Router} from './router';
import {createTraceLink, isDownloadable, shareTrace} from './trace_attrs';
import {
  convertToJson,
  convertTraceToJsonAndDownload,
  convertTraceToSystraceAndDownload,
} from './trace_converter';
import {HttpRpcEngine} from '../trace_processor/http_rpc_engine';

const GITILES_URL =
  'https://android.googlesource.com/platform/external/perfetto';

let lastTabTitle = '';

function getBugReportUrl(): string {
  if (globals.isInternalUser) {
    return 'https://goto.google.com/perfetto-ui-bug';
  } else {
    return 'https://github.com/google/perfetto/issues/new';
  }
}

const HIRING_BANNER_FLAG = featureFlags.register({
  id: 'showHiringBanner',
  name: 'Show hiring banner',
  description: 'Show the "We\'re hiring" banner link in the side bar.',
  defaultValue: false,
});

const WIDGETS_PAGE_IN_NAV_FLAG = featureFlags.register({
  id: 'showWidgetsPageInNav',
  name: 'Show widgets page',
  description: 'Show a link to the widgets page in the side bar.',
  defaultValue: false,
});

const PLUGINS_PAGE_IN_NAV_FLAG = featureFlags.register({
  id: 'showPluginsPageInNav',
  name: 'Show plugins page',
  description: 'Show a link to the plugins page in the side bar.',
  defaultValue: false,
});

const INSIGHTS_PAGE_IN_NAV_FLAG = featureFlags.register({
  id: 'showInsightsPageInNav',
  name: 'Show insights page',
  description: 'Show a link to the insights page in the side bar.',
  defaultValue: false,
});

const VIZ_PAGE_IN_NAV_FLAG = featureFlags.register({
  id: 'showVizPageInNav',
  name: 'Show viz page',
  description: 'Show a link to the viz page in the side bar.',
  defaultValue: true,
});

function shouldShowHiringBanner(): boolean {
  return globals.isInternalUser && HIRING_BANNER_FLAG.get();
}

export const EXAMPLE_ANDROID_TRACE_URL =
  'https://storage.googleapis.com/perfetto-misc/example_android_trace_15s';

export const EXAMPLE_CHROME_TRACE_URL =
  'https://storage.googleapis.com/perfetto-misc/chrome_example_wikipedia.perfetto_trace.gz';

interface SectionItem {
  t: string;
  a: string | ((e: Event) => void);
  i: string;
  isPending?: () => boolean;
  isVisible?: () => boolean;
  internalUserOnly?: boolean;
  checkDownloadDisabled?: boolean;
  checkMetatracingEnabled?: boolean;
  checkMetatracingDisabled?: boolean;
}

interface Section {
  title: string;
  summary: string;
  items: SectionItem[];
  expanded?: boolean;
  hideIfNoTraceLoaded?: boolean;
  appendOpenedTraceTitle?: boolean;
}

function getSections(): Section[] {
  return [
    {
      title: 'Navigation',
      summary: 'Open or record a new trace',
      expanded: true,
      items: [
        {t: 'Open trace file', a: popupFileSelectionDialog, i: 'folder_open'},
        {
          t: 'Open with legacy UI',
          a: popupFileSelectionDialogOldUI,
          i: 'filter_none',
        },
        {t: 'Record new trace', a: navigateRecord, i: 'fiber_smart_record'},
        {
          t: 'Widgets',
          a: navigateWidgets,
          i: 'widgets',
          isVisible: () => WIDGETS_PAGE_IN_NAV_FLAG.get(),
        },
        {
          t: 'Plugins',
          a: navigatePlugins,
          i: 'extension',
          isVisible: () => PLUGINS_PAGE_IN_NAV_FLAG.get(),
        },
      ],
    },

    {
      title: 'Current Trace',
      summary: 'Actions on the current trace',
      expanded: true,
      hideIfNoTraceLoaded: true,
      appendOpenedTraceTitle: true,
      items: [
        {t: 'Show timeline', a: navigateViewer, i: 'line_style'},
        {
          t: 'Share',
          a: handleShareTrace,
          i: 'share',
          internalUserOnly: true,
          isPending: () =>
            globals.getConversionJobStatus('create_permalink') ===
            ConversionJobStatus.InProgress,
        },
        {
          t: 'Download',
          a: downloadTrace,
          i: 'file_download',
          checkDownloadDisabled: true,
        },
        {t: 'Query (SQL)', a: navigateQuery, i: 'database'},
        {
          t: 'Insights',
          a: navigateInsights,
          i: 'insights',
          isVisible: () => INSIGHTS_PAGE_IN_NAV_FLAG.get(),
        },
        {
          t: 'Viz',
          a: navigateViz,
          i: 'area_chart',
          isVisible: () => VIZ_PAGE_IN_NAV_FLAG.get(),
        },
        {t: 'Metrics', a: navigateMetrics, i: 'speed'},
        {t: 'Info and stats', a: navigateInfo, i: 'info'},
      ],
    },

    {
      title: 'Convert trace',
      summary: 'Convert to other formats',
      expanded: true,
      hideIfNoTraceLoaded: true,
      items: [
        {
          t: 'Switch to legacy UI',
          a: openCurrentTraceWithOldUI,
          i: 'filter_none',
          isPending: () =>
            globals.getConversionJobStatus('open_in_legacy') ===
            ConversionJobStatus.InProgress,
        },
        {
          t: 'Convert to .json',
          a: convertTraceToJson,
          i: 'file_download',
          isPending: () =>
            globals.getConversionJobStatus('convert_json') ===
            ConversionJobStatus.InProgress,
          checkDownloadDisabled: true,
        },

        {
          t: 'Convert to .systrace',
          a: convertTraceToSystrace,
          i: 'file_download',
          isVisible: () => globals.hasFtrace,
          isPending: () =>
            globals.getConversionJobStatus('convert_systrace') ===
            ConversionJobStatus.InProgress,
          checkDownloadDisabled: true,
        },
      ],
    },

    {
      title: 'Example Traces',
      expanded: true,
      summary: 'Open an example trace',
      items: [
        {
          t: 'Open Android example',
          a: openTraceUrl(EXAMPLE_ANDROID_TRACE_URL),
          i: 'description',
        },
        {
          t: 'Open Chrome example',
          a: openTraceUrl(EXAMPLE_CHROME_TRACE_URL),
          i: 'description',
        },
      ],
    },

    {
      title: 'Support',
      expanded: true,
      summary: 'Documentation & Bugs',
      items: [
        {t: 'Keyboard shortcuts', a: openHelp, i: 'help'},
        {t: 'Documentation', a: 'https://perfetto.dev/docs', i: 'find_in_page'},
        {t: 'Flags', a: navigateFlags, i: 'emoji_flags'},
        {
          t: 'Report a bug',
          a: getBugReportUrl(),
          i: 'bug_report',
        },
        {
          t: 'Record metatrace',
          a: recordMetatrace,
          i: 'fiber_smart_record',
          checkMetatracingDisabled: true,
        },
        {
          t: 'Finalise metatrace',
          a: finaliseMetatrace,
          i: 'file_download',
          checkMetatracingEnabled: true,
        },
      ],
    },
  ];
}

function openHelp(e: Event) {
  e.preventDefault();
  toggleHelp();
}

function getFileElement(): HTMLInputElement {
  return assertExists(
    document.querySelector<HTMLInputElement>('input[type=file]'),
  );
}

function popupFileSelectionDialog(e: Event) {
  e.preventDefault();
  delete getFileElement().dataset['useCatapultLegacyUi'];
  getFileElement().click();
}

function popupFileSelectionDialogOldUI(e: Event) {
  e.preventDefault();
  getFileElement().dataset['useCatapultLegacyUi'] = '1';
  getFileElement().click();
}

function downloadTraceFromUrl(url: string): Promise<File> {
  return m.request({
    method: 'GET',
    url,
    // TODO(hjd): Once mithril is updated we can use responseType here rather
    // than using config and remove the extract below.
    config: (xhr) => {
      xhr.responseType = 'blob';
      xhr.onprogress = (progress) => {
        const percent = ((100 * progress.loaded) / progress.total).toFixed(1);
        globals.dispatch(
          Actions.updateStatus({
            msg: `Downloading trace ${percent}%`,
            timestamp: Date.now() / 1000,
          }),
        );
      };
    },
    extract: (xhr) => {
      return xhr.response;
    },
  });
}

export async function getCurrentTrace(): Promise<Blob> {
  // Caller must check engine exists.
  const engine = assertExists(globals.getCurrentEngine());
  const src = engine.source;
  if (src.type === 'ARRAY_BUFFER') {
    return new Blob([src.buffer]);
  } else if (src.type === 'FILE') {
    return src.file;
  } else if (src.type === 'URL') {
    return downloadTraceFromUrl(src.url);
  } else {
    throw new Error(`Loading to catapult from source with type ${src.type}`);
  }
}

function openCurrentTraceWithOldUI(e: Event) {
  e.preventDefault();
  assertTrue(isTraceLoaded());
  globals.logging.logEvent('Trace Actions', 'Open current trace in legacy UI');
  if (!isTraceLoaded()) return;
  getCurrentTrace()
    .then((file) => {
      openInOldUIWithSizeCheck(file);
    })
    .catch((error) => {
      throw new Error(`Failed to get current trace ${error}`);
    });
}

function convertTraceToSystrace(e: Event) {
  e.preventDefault();
  assertTrue(isTraceLoaded());
  globals.logging.logEvent('Trace Actions', 'Convert to .systrace');
  if (!isTraceLoaded()) return;
  getCurrentTrace()
    .then((file) => {
      convertTraceToSystraceAndDownload(file);
    })
    .catch((error) => {
      throw new Error(`Failed to get current trace ${error}`);
    });
}

function convertTraceToJson(e: Event) {
  e.preventDefault();
  assertTrue(isTraceLoaded());
  globals.logging.logEvent('Trace Actions', 'Convert to .json');
  if (!isTraceLoaded()) return;
  getCurrentTrace()
    .then((file) => {
      convertTraceToJsonAndDownload(file);
    })
    .catch((error) => {
      throw new Error(`Failed to get current trace ${error}`);
    });
}

export function isTraceLoaded(): boolean {
  return globals.getCurrentEngine() !== undefined;
}

export function openTraceUrl(url: string): (e: Event) => void {
  return (e) => {
    globals.logging.logEvent('Trace Actions', 'Open example trace');
    e.preventDefault();
    globals.dispatch(Actions.openTraceFromUrl({url}));
  };
}

function onInputElementFileSelectionChanged(e: Event) {
  if (!(e.target instanceof HTMLInputElement)) {
    throw new Error('Not an input element');
  }
  if (!e.target.files) return;
  const file = e.target.files[0];
  // Reset the value so onchange will be fired with the same file.
  e.target.value = '';

  if (e.target.dataset['useCatapultLegacyUi'] === '1') {
    openWithLegacyUi(file);
    return;
  }

  globals.logging.logEvent('Trace Actions', 'Open trace from file');
  globals.dispatch(Actions.openTraceFromFile({file}));
}

async function openWithLegacyUi(file: File) {
  // Switch back to the old catapult UI.
  globals.logging.logEvent('Trace Actions', 'Open trace in Legacy UI');
  if (await isLegacyTrace(file)) {
    openFileWithLegacyTraceViewer(file);
    return;
  }
  openInOldUIWithSizeCheck(file);
}

function openInOldUIWithSizeCheck(trace: Blob) {
  // Perfetto traces smaller than 50mb can be safely opened in the legacy UI.
  if (trace.size < 1024 * 1024 * 50) {
    convertToJson(trace);
    return;
  }

  // Give the user the option to truncate larger perfetto traces.
  const size = Math.round(trace.size / (1024 * 1024));
  showModal({
    title: 'Legacy UI may fail to open this trace',
    content: m(
      'div',
      m(
        'p',
        `This trace is ${size}mb, opening it in the legacy UI ` + `may fail.`,
      ),
      m(
        'p',
        'More options can be found at ',
        m(
          'a',
          {
            href: 'https://goto.google.com/opening-large-traces',
            target: '_blank',
          },
          'go/opening-large-traces',
        ),
        '.',
      ),
    ),
    buttons: [
      {
        text: 'Open full trace (not recommended)',
        action: () => convertToJson(trace),
      },
      {
        text: 'Open beginning of trace',
        action: () => convertToJson(trace, /* truncate*/ 'start'),
      },
      {
        text: 'Open end of trace',
        primary: true,
        action: () => convertToJson(trace, /* truncate*/ 'end'),
      },
    ],
  });
  return;
}

function navigateRecord(e: Event) {
  e.preventDefault();
  Router.navigate('#!/record');
}

function navigateWidgets(e: Event) {
  e.preventDefault();
  Router.navigate('#!/widgets');
}

function navigatePlugins(e: Event) {
  e.preventDefault();
  Router.navigate('#!/plugins');
}

function navigateQuery(e: Event) {
  e.preventDefault();
  Router.navigate('#!/query');
}

function navigateInsights(e: Event) {
  e.preventDefault();
  Router.navigate('#!/insights');
}

function navigateViz(e: Event) {
  e.preventDefault();
  Router.navigate('#!/viz');
}

function navigateFlags(e: Event) {
  e.preventDefault();
  Router.navigate('#!/flags');
}

function navigateMetrics(e: Event) {
  e.preventDefault();
  Router.navigate('#!/metrics');
}

function navigateInfo(e: Event) {
  e.preventDefault();
  Router.navigate('#!/info');
}

function navigateViewer(e: Event) {
  e.preventDefault();
  Router.navigate('#!/viewer');
}

function handleShareTrace(e: Event) {
  e.preventDefault();
  shareTrace();
}

function downloadTrace(e: Event) {
  e.preventDefault();
  if (!isDownloadable() || !isTraceLoaded()) return;
  globals.logging.logEvent('Trace Actions', 'Download trace');

  const engine = globals.getCurrentEngine();
  if (!engine) return;
  let url = '';
  let fileName = `trace${TRACE_SUFFIX}`;
  const src = engine.source;
  if (src.type === 'URL') {
    url = src.url;
    fileName = url.split('/').slice(-1)[0];
  } else if (src.type === 'ARRAY_BUFFER') {
    const blob = new Blob([src.buffer], {type: 'application/octet-stream'});
    const inputFileName = window.prompt(
      'Please enter a name for your file or leave blank',
    );
    if (inputFileName) {
      fileName = `${inputFileName}.perfetto_trace.gz`;
    } else if (src.fileName) {
      fileName = src.fileName;
    }
    url = URL.createObjectURL(blob);
  } else if (src.type === 'FILE') {
    const file = src.file;
    url = URL.createObjectURL(file);
    fileName = file.name;
  } else {
    throw new Error(`Download from ${JSON.stringify(src)} is not supported`);
  }
  downloadUrl(fileName, url);
}

function getCurrentEngine(): Engine | undefined {
  const engineId = globals.getCurrentEngine()?.id;
  if (engineId === undefined) return undefined;
  return globals.engines.get(engineId);
}

function highPrecisionTimersAvailable(): boolean {
  // High precision timers are available either when the page is cross-origin
  // isolated or when the trace processor is a standalone binary.
  return (
    window.crossOriginIsolated ||
    globals.getCurrentEngine()?.mode === 'HTTP_RPC'
  );
}

function recordMetatrace(e: Event) {
  e.preventDefault();
  globals.logging.logEvent('Trace Actions', 'Record metatrace');

  const engine = getCurrentEngine();
  if (!engine) return;

  if (!highPrecisionTimersAvailable()) {
    const PROMPT = `High-precision timers are not available to WASM trace processor yet.

Modern browsers restrict high-precision timers to cross-origin-isolated pages.
As Perfetto UI needs to open traces via postMessage, it can't be cross-origin
isolated until browsers ship support for
'Cross-origin-opener-policy: restrict-properties'.

Do you still want to record a metatrace?
Note that events under timer precision (1ms) will dropped.
Alternatively, connect to a trace_processor_shell --httpd instance.
`;
    showModal({
      title: `Trace processor doesn't have high-precision timers`,
      content: m('.modal-pre', PROMPT),
      buttons: [
        {
          text: 'YES, record metatrace',
          primary: true,
          action: () => {
            enableMetatracing();
            engine.enableMetatrace();
          },
        },
        {
          text: 'NO, cancel',
        },
      ],
    });
  } else {
    engine.enableMetatrace();
  }
}

async function finaliseMetatrace(e: Event) {
  e.preventDefault();
  globals.logging.logEvent('Trace Actions', 'Finalise metatrace');

  const jsEvents = disableMetatracingAndGetTrace();

  const engine = getCurrentEngine();
  if (!engine) return;

  const result = await engine.stopAndGetMetatrace();
  if (result.error.length !== 0) {
    throw new Error(`Failed to read metatrace: ${result.error}`);
  }

  downloadData('metatrace', result.metatrace, jsEvents);
}

const EngineRPCWidget: m.Component = {
  view() {
    let cssClass = '';
    let title = 'Number of pending SQL queries';
    let label: string;
    let failed = false;
    let mode: EngineMode | undefined;

    const engine = globals.state.engine;
    if (engine !== undefined) {
      mode = engine.mode;
      if (engine.failed !== undefined) {
        cssClass += '.red';
        title = 'Query engine crashed\n' + engine.failed;
        failed = true;
      }
    }

    // If we don't have an engine yet, guess what will be the mode that will
    // be used next time we'll create one. Even if we guess it wrong (somehow
    // trace_controller.ts takes a different decision later, e.g. because the
    // RPC server is shut down after we load the UI and cached httpRpcState)
    // this will eventually become  consistent once the engine is created.
    if (mode === undefined) {
      if (
        globals.httpRpcState.connected &&
        globals.state.newEngineMode === 'USE_HTTP_RPC_IF_AVAILABLE'
      ) {
        mode = 'HTTP_RPC';
      } else {
        mode = 'WASM';
      }
    }

    if (mode === 'HTTP_RPC') {
      cssClass += '.green';
      label = 'RPC';
      title += '\n(Query engine: native accelerator over HTTP+RPC)';
    } else {
      label = 'WSM';
      title += '\n(Query engine: built-in WASM)';
    }

    return m(
      `.dbg-info-square${cssClass}`,
      {title},
      m('div', label),
      m('div', `${failed ? 'FAIL' : globals.numQueuedQueries}`),
    );
  },
};

const ServiceWorkerWidget: m.Component = {
  view() {
    let cssClass = '';
    let title = 'Service Worker: ';
    let label = 'N/A';
    const ctl = globals.serviceWorkerController;
    if (!('serviceWorker' in navigator)) {
      label = 'N/A';
      title += 'not supported by the browser (requires HTTPS)';
    } else if (ctl.bypassed) {
      label = 'OFF';
      cssClass = '.red';
      title += 'Bypassed, using live network. Double-click to re-enable';
    } else if (ctl.installing) {
      label = 'UPD';
      cssClass = '.amber';
      title += 'Installing / updating ...';
    } else if (!navigator.serviceWorker.controller) {
      label = 'N/A';
      title += 'Not available, using network';
    } else {
      label = 'ON';
      cssClass = '.green';
      title += 'Serving from cache. Ready for offline use';
    }

    const toggle = async () => {
      if (globals.serviceWorkerController.bypassed) {
        globals.serviceWorkerController.setBypass(false);
        return;
      }
      showModal({
        title: 'Disable service worker?',
        content: m(
          'div',
          m(
            'p',
            `If you continue the service worker will be disabled until
                      manually re-enabled.`,
          ),
          m(
            'p',
            `All future requests will be served from the network and the
                    UI won't be available offline.`,
          ),
          m(
            'p',
            `You should do this only if you are debugging the UI
                    or if you are experiencing caching-related problems.`,
          ),
          m(
            'p',
            `Disabling will cause a refresh of the UI, the current state
                    will be lost.`,
          ),
        ),
        buttons: [
          {
            text: 'Disable and reload',
            primary: true,
            action: () => {
              globals.serviceWorkerController
                .setBypass(true)
                .then(() => location.reload());
            },
          },
          {text: 'Cancel'},
        ],
      });
    };

    return m(
      `.dbg-info-square${cssClass}`,
      {title, ondblclick: toggle},
      m('div', 'SW'),
      m('div', label),
    );
  },
};

const SidebarFooter: m.Component = {
  view() {
    return m(
      '.sidebar-footer',
      m(EngineRPCWidget),
      m(ServiceWorkerWidget),
      m(
        '.version',
        m(
          'a',
          {
            href: `${GITILES_URL}/+/${SCM_REVISION}/ui`,
            title: `Channel: ${getCurrentChannel()}`,
            target: '_blank',
          },
          VERSION,
        ),
      ),
    );
  },
};

class HiringBanner implements m.ClassComponent {
  view() {
    return m(
      '.hiring-banner',
      m(
        'a',
        {
          href: 'http://go/perfetto-open-roles',
          target: '_blank',
        },
        "We're hiring!",
      ),
    );
  }
}

export class Sidebar implements m.ClassComponent {
  private _redrawWhileAnimating = new Animation(() => raf.scheduleFullRedraw());
  view() {
    if (globals.hideSidebar) return null;
    const vdomSections = [];
    for (const section of getSections()) {
      if (section.hideIfNoTraceLoaded && !isTraceLoaded()) continue;
      const vdomItems = [];
      for (const item of section.items) {
        if (item.isVisible !== undefined && !item.isVisible()) {
          continue;
        }
        let css = '';
        let attrs = {
          onclick: typeof item.a === 'function' ? item.a : null,
          href: isString(item.a) ? item.a : '#',
          target: isString(item.a) ? '_blank' : null,
          disabled: false,
          id: item.t.toLowerCase().replace(/[^\w]/g, '_'),
        };
        if (item.isPending && item.isPending()) {
          attrs.onclick = (e) => e.preventDefault();
          css = '.pending';
        }
        if (item.internalUserOnly && !globals.isInternalUser) {
          continue;
        }
        if (item.checkMetatracingEnabled || item.checkMetatracingDisabled) {
          if (
            item.checkMetatracingEnabled === true &&
            !isMetatracingEnabled()
          ) {
            continue;
          }
          if (
            item.checkMetatracingDisabled === true &&
            isMetatracingEnabled()
          ) {
            continue;
          }
          if (
            item.checkMetatracingDisabled &&
            !highPrecisionTimersAvailable()
          ) {
            attrs.disabled = true;
          }
        }
        if (item.checkDownloadDisabled && !isDownloadable()) {
          attrs = {
            onclick: (e) => {
              e.preventDefault();
              alert('Can not download external trace.');
            },
            href: '#',
            target: null,
            disabled: true,
            id: '',
          };
        }
        vdomItems.push(
          m('li', m(`a${css}`, attrs, m('i.material-icons', item.i), item.t)),
        );
      }
      if (section.appendOpenedTraceTitle) {
        const engine = globals.state.engine;
        if (engine !== undefined) {
          let traceTitle = '';
          let traceUrl = '';
          switch (engine.source.type) {
            case 'FILE':
              // Split on both \ and / (because C:\Windows\paths\are\like\this).
              traceTitle = engine.source.file.name.split(/[/\\]/).pop()!;
              const fileSizeMB = Math.ceil(engine.source.file.size / 1e6);
              traceTitle += ` (${fileSizeMB} MB)`;
              break;
            case 'URL':
              traceUrl = engine.source.url;
              traceTitle = traceUrl.split('/').pop()!;
              break;
            case 'ARRAY_BUFFER':
              traceTitle = engine.source.title;
              traceUrl = engine.source.url || '';
              const arrayBufferSizeMB = Math.ceil(
                engine.source.buffer.byteLength / 1e6,
              );
              traceTitle += ` (${arrayBufferSizeMB} MB)`;
              break;
            case 'HTTP_RPC':
              traceTitle = `RPC @ ${HttpRpcEngine.hostAndPort}`;
              break;
            default:
              break;
          }
          if (traceTitle !== '') {
            const tabTitle = `${traceTitle} - Perfetto UI`;
            if (tabTitle !== lastTabTitle) {
              document.title = lastTabTitle = tabTitle;
            }
            vdomItems.unshift(m('li', createTraceLink(traceTitle, traceUrl)));
          }
        }
      }
      vdomSections.push(
        m(
          `section${section.expanded ? '.expanded' : ''}`,
          m(
            '.section-header',
            {
              onclick: () => {
                section.expanded = !section.expanded;
                raf.scheduleFullRedraw();
              },
            },
            m('h1', {title: section.summary}, section.title),
            m('h2', section.summary),
          ),
          m('.section-content', m('ul', vdomItems)),
        ),
      );
    }
    return m(
      'nav.sidebar',
      {
        class: globals.state.sidebarVisible ? 'show-sidebar' : 'hide-sidebar',
        // 150 here matches --sidebar-timing in the css.
        // TODO(hjd): Should link to the CSS variable.
        ontransitionstart: (e: TransitionEvent) => {
          if (e.target !== e.currentTarget) return;
          this._redrawWhileAnimating.start(150);
        },
        ontransitionend: (e: TransitionEvent) => {
          if (e.target !== e.currentTarget) return;
          this._redrawWhileAnimating.stop();
        },
      },
      shouldShowHiringBanner() ? m(HiringBanner) : null,
      m(
        `header.${getCurrentChannel()}`,
        m(`img[src=${globals.root}assets/brand.png].brand`),
        m(
          'button.sidebar-button',
          {
            onclick: () => {
              globals.commandManager.runCommand(
                'dev.perfetto.CoreCommands#ToggleLeftSidebar',
              );
            },
          },
          m(
            'i.material-icons',
            {
              title: globals.state.sidebarVisible ? 'Hide menu' : 'Show menu',
            },
            'menu',
          ),
        ),
      ),
      m('input.trace_file[type=file]', {
        onchange: onInputElementFileSelectionChanged,
      }),
      m(
        '.sidebar-scroll',
        m('.sidebar-scroll-container', ...vdomSections, m(SidebarFooter)),
      ),
    );
  }
}
