// 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(data => {
      // No messages expected yet coming out of the webview.
    });

    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() {
    this.process?.stop();
    this.process = this.ffx.runLog(this.currentDevice, (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, 'dist', 'webviews-logging.css'));

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

    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="${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;
  }
}
