// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as vscode from 'vscode';
import { Ffx, FfxLog, FuchsiaDevice } from '../ffx';
import * as logger from '../logger';

export const TOGGLE_LOG_VIEW_COMMAND = 'workbench.view.extension.fuchsia-logging';

export class LoggingViewProvider implements vscode.WebviewViewProvider {
  public static readonly viewType = 'vscode-fuchsia.loggingView';

  private view?: vscode.WebviewView;
  private process?: FfxLog;
  private currentDevice?: string;
  private lastVisibilitySeen: boolean = false;

  constructor(
    private readonly extensionUri: vscode.Uri,
    private readonly ffx: Ffx,
  ) {
    // NB: we're explicitly using an async closure here
    // event tho onSetTarget isn't expecting it.  We're doing
    // UI operations in response to events, it's fine to run
    // "in the background"
    this.ffx.onSetTarget(async (device) => {
      if (this.currentDevice !== device?.nodeName) {
        this.currentDevice = device?.nodeName;
        if (this.view?.visible) {
          await this.resetView();
          this.startListeningForLogs();
        }
      }
    });
  }

  public get currentTargetDevice(): string | undefined {
    return this.currentDevice;
  }

  public resolveWebviewView(
    webviewView: vscode.WebviewView,
    context: vscode.WebviewViewResolveContext<unknown>,
    token: vscode.CancellationToken
  ): void {
    this.startListeningForLogs();

    this.view = webviewView;

    webviewView.webview.options = {
      // Allow scripts in the webview
      enableScripts: true,

      localResourceRoots: [
        this.extensionUri
      ]
    };

    webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);

    webviewView.webview.onDidReceiveMessage(message => {
      switch (message.command) {
        case 'pauseLogStreaming':
          this.process?.stop();
          break;
        case 'resumeLogStreaming':
          this.startListeningForLogs('now');
          break;
      }
    });

    this.lastVisibilitySeen = this.view.visible;
    this.view.onDidChangeVisibility(() => {
      if (!this.view?.visible) {
        // If the view is hidden, we stop ffx.
        this.lastVisibilitySeen = false;
        this.process?.stop();
      } else if (!this.lastVisibilitySeen) {
        // If the view was hidden and it becomes visible then we re-run ffx
        this.lastVisibilitySeen = true;
        this.startListeningForLogs();
      }
    });
  }

  public async resetAndShowView(device: FuchsiaDevice | undefined) {
    // If the device changed, update it.
    if (this.currentDevice !== device?.nodeName) {
      this.currentDevice = device?.nodeName;

      // If the device changed and the view was already visible, clear it and start
      // streaming logs from the new device.
      if (this.view?.visible) {
        await this.resetView();
        this.startListeningForLogs();
        return;
      }
    }

    // If we don't have a webview, make sure to create one.
    if (this.view === undefined) {
      await vscode.commands.executeCommand(TOGGLE_LOG_VIEW_COMMAND);
    }

    // If the view wasn't visible, make it visible. This will result in streaming logs for the
    // currently selected device.
    if (!this.view?.visible) {
      this.view?.show();
    }
  }

  private async addLog(log: Object) {
    await this.view?.webview.postMessage({ type: 'addLog', log });
  }

  private async resetView() {
    await this.view?.webview.postMessage({ type: 'reset' });
  }

  private startListeningForLogs(since?: string) {
    this.process?.stop();
    const args = since ? ['--since', since] : [];
    this.process = this.ffx.runLog(this.currentDevice, args, (data: Object) => {
      // this was... not marked async before, but postMessage is an async operation
      // so there's not much to do about this here.  We've gotta just go async & hope.
      this.addLog(data).catch((err) => logger.error('unable to show log line', undefined, err));
    });
  }

  private _getHtmlForWebview(webview: vscode.Webview): string {
    // Get the local path to main script run in the webview, then convert it to a uri we can use in
    // the webview.
    const scriptUri = webview.asWebviewUri(
      vscode.Uri.joinPath(this.extensionUri, 'dist', 'webviews-logging.js'));

    // Do the same for the stylesheet.
    const styleResetUri = webview.asWebviewUri(
      vscode.Uri.joinPath(this.extensionUri, 'media', 'reset.css'));
    const styleVSCodeUri = webview.asWebviewUri(
      vscode.Uri.joinPath(this.extensionUri, 'media', 'vscode.css'));
    const styleMainUri = webview.asWebviewUri(
      vscode.Uri.joinPath(this.extensionUri, 'media', 'webview-logging.css'));
    const codiconsUri = webview.asWebviewUri(
      vscode.Uri.joinPath(this.extensionUri, 'media', 'codicon.ttf'));
    const codiconsCssUri = webview.asWebviewUri(
      vscode.Uri.joinPath(this.extensionUri, 'media', 'codicon.css'));

    // Use a nonce to only allow a specific script to be run.
    const nonce = this.getNonce();

    // TODO(fxbug.dev/100046): remove the unsafe-inline CSP once the global stylesheet has been
    // elimiated since everything will be web components.
    return `<!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <!--
          Use a content security policy to only allow loading images from https or from our
          extension directory, and only allow scripts that have a specific nonce.
        -->
        <meta http-equiv="Content-Security-Policy" content="default-src 'none';
            style-src ${webview.cspSource};
            script-src 'nonce-${nonce}';
            font-src ${webview.cspSource}">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="${styleResetUri}" rel="stylesheet">
        <link href="${styleVSCodeUri}" rel="stylesheet">
        <link href="${codiconsUri}" rel="preload" as="font"/>
        <link href="${codiconsCssUri}" rel="stylesheet" />
        <link href="${styleMainUri}" rel="stylesheet">

        <title>Fuchsia Logs</title>
      </head>
      <body>
        <script nonce="${nonce}" src="${scriptUri}"></script>
      </body>
      </html>`;
  }

  private getNonce() {
    let text = '';
    const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    for (let i = 0; i < 32; i++) {
      text += possible.charAt(Math.floor(Math.random() * possible.length));
    }
    return text;
  }
}
