// 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.runFfxJsonStreaming(
      this.currentDevice,
      ['log', ...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 codiconsCssUri = webview.asWebviewUri(
      vscode.Uri.joinPath(this.extensionUri, 'media', 'codicon.css'));
    const codiconsUri = webview.asWebviewUri(
      vscode.Uri.joinPath(this.extensionUri, 'media', 'codicon.ttf'));

    // 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" crossorigin/>
        <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;
  }
}
