// Copyright (C) 2019 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 {ErrorDetails} from '../base/logging';
import {EXTENSION_URL} from '../common/recordingV2/recording_utils';
import {TraceGcsUploader} from '../common/upload_utils';
import {RECORDING_V2_FLAG} from '../core/feature_flags';
import {raf} from '../core/raf_scheduler';
import {VERSION} from '../gen/perfetto_version';
import {getCurrentModalKey, showModal} from '../widgets/modal';

import {globals} from './globals';

const MODAL_KEY = 'crash_modal';

// Never show more than one dialog per 10s.
const MIN_REPORT_PERIOD_MS = 10000;
let timeLastReport = 0;

export function maybeShowErrorDialog(err: ErrorDetails) {
  const now = performance.now();

  // Here we rely on the exception message from onCannotGrowMemory function
  if (
    err.message.includes('Cannot enlarge memory') ||
    err.stack.some((entry) => entry.name.includes('_emscripten_resize_heap')) ||
    err.stack.some((entry) => entry.name.includes('sbrk')) ||
    /^out of memory$/m.exec(err.message)
  ) {
    showOutOfMemoryDialog();
    // Refresh timeLastReport to prevent a different error showing a dialog
    timeLastReport = now;
    return;
  }

  if (!RECORDING_V2_FLAG.get()) {
    if (err.message.includes('Unable to claim interface')) {
      showWebUSBError();
      timeLastReport = now;
      return;
    }

    if (
      err.message.includes('A transfer error has occurred') ||
      err.message.includes('The device was disconnected') ||
      err.message.includes('The transfer was cancelled')
    ) {
      showConnectionLostError();
      timeLastReport = now;
      return;
    }
  }

  if (err.message.includes('(ERR:fmt)')) {
    showUnknownFileError();
    return;
  }

  if (err.message.includes('(ERR:rpc_seq)')) {
    showRpcSequencingError();
    return;
  }

  if (timeLastReport > 0 && now - timeLastReport <= MIN_REPORT_PERIOD_MS) {
    console.log('Suppressing crash dialog, last error notified too soon.');
    return;
  }
  timeLastReport = now;

  // If we are already showing a crash dialog, don't overwrite it with a newer
  // crash. Usually the first crash matters, the rest avalanching effects.
  if (getCurrentModalKey() === MODAL_KEY) {
    return;
  }

  showModal({
    key: MODAL_KEY,
    title: 'Oops, something went wrong. Please file a bug.',
    content: () => m(ErrorDialogComponent, err),
  });
}

class ErrorDialogComponent implements m.ClassComponent<ErrorDetails> {
  private traceState:
    | 'NOT_AVAILABLE'
    | 'NOT_UPLOADED'
    | 'UPLOADING'
    | 'UPLOADED';
  private traceType: string = 'No trace loaded';
  private traceData?: ArrayBuffer | File;
  private traceUrl?: string;
  private attachTrace = false;
  private uploadStatus = '';
  private userDescription = '';
  private errorMessage = '';
  private uploader?: TraceGcsUploader;

  constructor() {
    this.traceState = 'NOT_AVAILABLE';
    const engine = globals.getCurrentEngine();
    if (engine === undefined) return;
    this.traceType = engine.source.type;
    // If the trace is either already uploaded, or comes from a postmessage+url
    // we don't need any re-upload.
    if ('url' in engine.source && engine.source.url !== undefined) {
      this.traceUrl = engine.source.url;
      this.traceState = 'UPLOADED';
      // The trace is already uploaded, so assume the user is fine attaching to
      // the bugreport (this make the checkbox ticked by default).
      this.attachTrace = true;
      return;
    }

    // If the user is not a googler, don't even offer the option to upload it.
    if (!globals.isInternalUser) return;

    if (engine.source.type === 'FILE') {
      this.traceState = 'NOT_UPLOADED';
      this.traceData = engine.source.file;
      // this.traceSize = this.traceData.size;
    } else if (engine.source.type === 'ARRAY_BUFFER') {
      this.traceData = engine.source.buffer;
      // this.traceSize = this.traceData.byteLength;
    } else {
      return; // Can't upload HTTP+RPC.
    }
    this.traceState = 'NOT_UPLOADED';
  }

  view(vnode: m.Vnode<ErrorDetails>) {
    const err = vnode.attrs;
    let msg = `UI: ${location.protocol}//${location.host}/${VERSION}\n\n`;

    // Append the trace stack.
    msg += `${err.message}\n`;
    for (const entry of err.stack) {
      msg += ` - ${entry.name} (${entry.location})\n`;
    }
    msg += '\n';

    // Append the trace URL.
    if (this.attachTrace && this.traceUrl) {
      msg += `Trace: ${this.traceUrl}\n`;
    } else if (this.attachTrace && this.traceState === 'UPLOADING') {
      msg += `Trace: uploading...\n`;
    } else {
      msg += `Trace: not available (${this.traceType}). Provide repro steps.\n`;
    }
    msg += `UA: ${navigator.userAgent}\n`;
    msg += `Referrer: ${document.referrer}\n`;
    this.errorMessage = msg;

    let shareTraceSection: m.Vnode | null = null;
    if (this.traceState !== 'NOT_AVAILABLE') {
      shareTraceSection = m(
        'div',
        m(
          'label',
          m(`input[type=checkbox]`, {
            checked: this.attachTrace,
            oninput: (ev: InputEvent) => {
              const checked = (ev.target as HTMLInputElement).checked;
              this.onUploadCheckboxChange(checked);
            },
          }),
          this.traceState === 'UPLOADING'
            ? `Uploading trace... ${this.uploadStatus}`
            : 'Tick to share the current trace and help debugging',
        ), // m('label')
        m(
          'div.modal-small',
          `This will upload the trace and attach a link to the bug.
          You may leave it unchecked and attach the trace manually to the bug
          if preferred.`,
        ),
      );
    } // if (this.traceState !== 'NOT_AVAILABLE')

    return [
      m(
        'div',
        m('.modal-logs', msg),
        m(
          'span',
          `Please provide any additional details describing
        how the crash occurred:`,
        ),
        m('textarea.modal-textarea', {
          rows: 3,
          maxlength: 1000,
          oninput: (ev: InputEvent) => {
            this.userDescription = (ev.target as HTMLTextAreaElement).value;
          },
          onkeydown: (e: Event) => e.stopPropagation(),
          onkeyup: (e: Event) => e.stopPropagation(),
        }),
        shareTraceSection,
      ),
      m(
        'footer',
        m(
          'button.modal-btn.modal-btn-primary',
          {onclick: () => this.fileBug(err)},
          'File a bug (Googlers only)',
        ),
      ),
    ];
  }

  private onUploadCheckboxChange(checked: boolean) {
    raf.scheduleFullRedraw();
    this.attachTrace = checked;

    if (
      checked &&
      this.traceData !== undefined &&
      this.traceState === 'NOT_UPLOADED'
    ) {
      this.traceState = 'UPLOADING';
      this.uploadStatus = '';
      const uploader = new TraceGcsUploader(this.traceData, () => {
        raf.scheduleFullRedraw();
        this.uploadStatus = uploader.getEtaString();
        if (uploader.state === 'UPLOADED') {
          this.traceState = 'UPLOADED';
          this.traceUrl = uploader.uploadedUrl;
        } else if (uploader.state === 'ERROR') {
          this.traceState = 'NOT_UPLOADED';
          this.uploadStatus = uploader.error;
        }
      });
      this.uploader = uploader;
    } else if (!checked && this.uploader) {
      this.uploader.abort();
    }
  }

  private fileBug(err: ErrorDetails) {
    const errTitle = err.message.split('\n', 1)[0].substring(0, 80);
    let url = 'https://goto.google.com/perfetto-ui-bug';
    url += '?title=' + encodeURIComponent(`UI Error: ${errTitle}`);
    url += '&description=';
    if (this.userDescription !== '') {
      url += encodeURIComponent(
        'User description:\n' + this.userDescription + '\n\n',
      );
    }
    url += encodeURIComponent(this.errorMessage);
    // 8kb is common limit on request size so restrict links to that long:
    url = url.substring(0, 8000);
    window.open(url, '_blank');
  }
}

function showOutOfMemoryDialog() {
  const url =
    'https://perfetto.dev/docs/quickstart/trace-analysis#get-trace-processor';

  const tpCmd =
    'curl -LO https://get.perfetto.dev/trace_processor\n' +
    'chmod +x ./trace_processor\n' +
    'trace_processor --httpd /path/to/trace.pftrace\n' +
    '# Reload the UI, it will prompt to use the HTTP+RPC interface';
  showModal({
    title: 'Oops! Your WASM trace processor ran out of memory',
    content: m(
      'div',
      m(
        'span',
        'The in-memory representation of the trace is too big ' +
          'for the browser memory limits (typically 2GB per tab).',
      ),
      m('br'),
      m(
        'span',
        'You can work around this problem by using the trace_processor ' +
          'native binary as an accelerator for the UI as follows:',
      ),
      m('br'),
      m('br'),
      m('.modal-bash', tpCmd),
      m('br'),
      m('span', 'For details see '),
      m('a', {href: url, target: '_blank'}, url),
    ),
  });
}

function showUnknownFileError() {
  showModal({
    title: 'Cannot open this file',
    content: m(
      'div',
      m(
        'p',
        "The file opened doesn't look like a Perfetto trace or any " +
          'other format recognized by the Perfetto TraceProcessor.',
      ),
      m('p', 'Formats supported:'),
      m(
        'ul',
        m('li', 'Perfetto protobuf trace'),
        m('li', 'chrome://tracing JSON'),
        m('li', 'Android systrace'),
        m('li', 'Fuchsia trace'),
        m('li', 'Ninja build log'),
      ),
    ),
  });
}

function showWebUSBError() {
  showModal({
    title: 'A WebUSB error occurred',
    content: m(
      'div',
      m(
        'span',
        `Is adb already running on the host? Run this command and
      try again.`,
      ),
      m('br'),
      m('.modal-bash', '> adb kill-server'),
      m('br'),
      m('span', 'For details see '),
      m('a', {href: 'http://b/159048331', target: '_blank'}, 'b/159048331'),
    ),
  });
}

export function showWebUSBErrorV2() {
  showModal({
    title: 'A WebUSB error occurred',
    content: m(
      'div',
      m(
        'span',
        `Is adb already running on the host? Run this command and
      try again.`,
      ),
      m('br'),
      m('.modal-bash', '> adb kill-server'),
      m('br'),
      // The statement below covers the following edge case:
      // 1. 'adb server' is running on the device.
      // 2. The user selects the new Android target, so we try to fetch the
      // OS version and do QSS.
      // 3. The error modal is shown.
      // 4. The user runs 'adb kill-server'.
      // At this point we don't have a trigger to try fetching the OS version
      // + QSS again. Therefore, the user will need to refresh the page.
      m(
        'span',
        "If after running 'adb kill-server', you don't see " +
          "a 'Start Recording' button on the page and you don't see " +
          "'Allow USB debugging' on the device, " +
          'you will need to reload this page.',
      ),
      m('br'),
      m('br'),
      m('span', 'For details see '),
      m('a', {href: 'http://b/159048331', target: '_blank'}, 'b/159048331'),
    ),
  });
}

export function showConnectionLostError(): void {
  showModal({
    title: 'Connection with the ADB device lost',
    content: m(
      'div',
      m('span', `Please connect the device again to restart the recording.`),
      m('br'),
    ),
  });
}

export function showAllowUSBDebugging(): void {
  showModal({
    title: 'Could not connect to the device',
    content: m(
      'div',
      m('span', 'Please allow USB debugging on the device.'),
      m('br'),
    ),
  });
}

export function showNoDeviceSelected(): void {
  showModal({
    title: 'No device was selected for recording',
    content: m(
      'div',
      m(
        'span',
        `If you want to connect to an ADB device,
           please select it from the list.`,
      ),
      m('br'),
    ),
  });
}

export function showExtensionNotInstalled(): void {
  showModal({
    title: 'Perfetto Chrome extension not installed',
    content: m(
      'div',
      m(
        '.note',
        `To trace Chrome from the Perfetto UI, you need to install our `,
        m('a', {href: EXTENSION_URL, target: '_blank'}, 'Chrome extension'),
        ' and then reload this page.',
      ),
      m('br'),
    ),
  });
}

export function showWebsocketConnectionIssue(message: string): void {
  showModal({
    title: 'Unable to connect to the device via websocket',
    content: m('div', m('span', message), m('br')),
  });
}

export function showIssueParsingTheTracedResponse(message: string): void {
  showModal({
    title:
      'A problem was encountered while connecting to' +
      ' the Perfetto tracing service',
    content: m('div', m('span', message), m('br')),
  });
}

export function showFailedToPushBinary(message: string): void {
  showModal({
    title: 'Failed to push a binary to the device',
    content: m(
      'div',
      m(
        'span',
        'This can happen if your Android device has an OS version lower ' +
          'than Q. Perfetto tried to push the latest version of its ' +
          'embedded binary but failed.',
      ),
      m('br'),
      m('br'),
      m('span', 'Error message:'),
      m('br'),
      m('span', message),
    ),
  });
}

function showRpcSequencingError() {
  showModal({
    title: 'A TraceProcessor RPC error occurred',
    content: m(
      'div',
      m('p', 'The trace processor RPC sequence ID was broken'),
      m(
        'p',
        `This can happen when using a HTTP trace processor instance and
either accidentally sharing this between multiple tabs or
restarting the trace processor while still in use by UI.`,
      ),
      m(
        'p',
        `Please refresh this tab and ensure that trace processor is used
at most one tab at a time.`,
      ),
    ),
  });
}
