// 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 assert from 'assert';
import * as vscode from 'vscode';

import { describe, it } from 'mocha';
import { createSandbox, SinonSandbox, SinonStubbedInstance } from 'sinon';

import { LoggingViewProvider, TOGGLE_LOG_VIEW_COMMAND } from '../../../logging/view_provider';
import { Ffx, FuchsiaDevice } from '../../../ffx';
import { JsonStreamProcess } from '../../../process';
import { StubbedSpawn } from '../utils';
import { ChildProcessWithoutNullStreams } from 'child_process';

describe('Logging view provider tests', function () {
  const sandbox = createSandbox();
  let ffx: SinonStubbedInstance<Ffx>;
  let uri: vscode.Uri;
  let provider: LoggingViewProvider;
  let targetEventEmitter: vscode.EventEmitter<FuchsiaDevice>;
  let executeCommandStub: any;

  this.beforeEach(() => {
    executeCommandStub = sandbox.stub(vscode.commands, 'executeCommand');
    uri = vscode.Uri.file('/fake/file');
    targetEventEmitter = new vscode.EventEmitter<FuchsiaDevice>();
    ffx = sandbox.createStubInstance(Ffx);
    (ffx as Ffx).onSetTarget = targetEventEmitter.event;
    provider = new LoggingViewProvider(uri, ffx);
  });

  this.afterEach(function () {
    sandbox.restore();
  });

  describe('visibility changes', () => {
    it('stops the ffx process when the view is hidden', () => {
      let fakeProcess = sandbox.createStubInstance(JsonStreamProcess);
      ffx.runFfxJsonStreaming.returns(fakeProcess);
      let provider = new LoggingViewProvider(uri, ffx);
      let visibilityEmitter = new vscode.EventEmitter<void>();
      let view = fakeWebviewView(
        sandbox, true, visibilityEmitter.event, new vscode.EventEmitter<any>().event);
      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });

      // This should trigger the creation of a process.
      visibilityEmitter.fire();

      (view as any).visible = false;
      visibilityEmitter.fire();
      assert.ok(fakeProcess.stop.calledOnce);
    });

    it('spawns an ffx process when the view appears', () => {
      let visibilityEmitter = new vscode.EventEmitter<void>();
      let view = fakeWebviewView(
        sandbox, true, visibilityEmitter.event, new vscode.EventEmitter<any>().event);
      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });
      visibilityEmitter.fire();
      assert.ok(ffx.runFfxJsonStreaming.calledOnce);
      assert.deepStrictEqual(ffx.runFfxJsonStreaming.getCall(0).args[0], undefined);
      assert.deepStrictEqual(ffx.runFfxJsonStreaming.getCall(0).args[1], ['log']);
    });

    it('spawns an ffx process when the view is resolved', () => {
      let visibilityEmitter = new vscode.EventEmitter<void>();
      let view = fakeWebviewView(
        sandbox, true, visibilityEmitter.event, new vscode.EventEmitter<any>().event);
      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });
      assert.ok(ffx.runFfxJsonStreaming.calledOnce);
      assert.deepStrictEqual(ffx.runFfxJsonStreaming.getCall(0).args[0], undefined);
      assert.deepStrictEqual(ffx.runFfxJsonStreaming.getCall(0).args[1], ['log']);
    });
  });

  describe('add a log', () => {
    it('pushes a log to the webview when received', () => {
      let process = new StubbedSpawn(sandbox);
      let ffx = new Ffx('foo');
      sandbox.stub(ffx, 'runFfxStreaming').returns(
        process.spawnEvent as ChildProcessWithoutNullStreams);
      let provider = new LoggingViewProvider(uri, ffx);

      let visibilityEmitter = new vscode.EventEmitter<void>();
      let view = fakeWebviewView(
        sandbox, true, visibilityEmitter.event, new vscode.EventEmitter<any>().event);
      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });

      // The view should be visible now.
      visibilityEmitter.fire();

      const data = '{"data":{"TargetLog": {}}}';
      process.spawnEvent.stdout?.emit('data', data);

      let webview = view.webview as sinon.SinonStubbedInstance<FakeWebview>;
      assert.ok(webview.postMessage.calledOnce);
      assert.deepStrictEqual(
        webview.postMessage.getCall(0).args[0],
        { type: 'addLog', log: JSON.parse(data) }
      );
    });

    it('handles logs that contain new lines', () => {
      let process = new StubbedSpawn(sandbox);
      let ffx = new Ffx('foo');
      sandbox.stub(ffx, 'runFfxStreaming').returns(
        process.spawnEvent as ChildProcessWithoutNullStreams);
      let provider = new LoggingViewProvider(uri, ffx);

      let visibilityEmitter = new vscode.EventEmitter<void>();
      let view = fakeWebviewView(
        sandbox, true, visibilityEmitter.event, new vscode.EventEmitter<any>().event);
      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });

      // Creates the process
      visibilityEmitter.fire();

      const data = `{"data":{"TargetLog": {"payload": {"message": "foo\\nbar"}}}}
      {"data": {"TargetLog": {"payload": {"message": "baz"}}}}`;
      process.stdout.emit('data', data);
      let webview = view.webview as SinonStubbedInstance<FakeWebview>;
      assert.ok(webview.postMessage.calledTwice);
      assert.deepStrictEqual(
        webview.postMessage.getCall(0).args[0],
        // eslint-disable-next-line @typescript-eslint/naming-convention
        { type: 'addLog', log: { data: { TargetLog: { payload: { message: 'foo\nbar' } } } } }
      );
      assert.deepStrictEqual(
        webview.postMessage.getCall(1).args[0],
        // eslint-disable-next-line @typescript-eslint/naming-convention
        { type: 'addLog', log: { data: { TargetLog: { payload: { message: 'baz' } } } } }
      );
    });
  });

  describe('#resetAndShowView', () => {
    it('toggles the view when there is no previous view', async () => {
      await provider.resetAndShowView(undefined);

      assert.ok(executeCommandStub.calledOnce);
      assert.strictEqual(
        executeCommandStub.getCall(0).args[0], TOGGLE_LOG_VIEW_COMMAND);
    });

    it('changes the current device and toggles the view when no previous view', async () => {
      assert.strictEqual(provider.currentTargetDevice, undefined);
      await provider.resetAndShowView(new FuchsiaDevice({ nodename: 'foo' }));
      assert.strictEqual(provider.currentTargetDevice, 'foo');
      assert.ok(executeCommandStub.calledOnce);
      assert.strictEqual(
        executeCommandStub.getCall(0).args[0], TOGGLE_LOG_VIEW_COMMAND);
    });

    it('resets the view when the device changes and the view is visible', async () => {
      let view = fakeWebviewView(
        sandbox, true, new vscode.EventEmitter<any>().event, new vscode.EventEmitter<any>().event);
      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });
      assert.ok(ffx.runFfxJsonStreaming.calledOnce);
      assert.deepStrictEqual(ffx.runFfxJsonStreaming.getCall(0).args[0], undefined);
      assert.deepStrictEqual(ffx.runFfxJsonStreaming.getCall(0).args[1], ['log']);

      await provider.resetAndShowView(new FuchsiaDevice({ nodename: 'foo' }));
      let webview = view.webview as SinonStubbedInstance<FakeWebview>;
      assert.ok(webview.postMessage.calledOnce);
      assert.deepStrictEqual(webview.postMessage.getCall(0).args[0], { type: 'reset' });
      assert.ok(ffx.runFfxJsonStreaming.calledTwice);
      assert.deepStrictEqual(ffx.runFfxJsonStreaming.getCall(1).args[0], 'foo');
      assert.deepStrictEqual(ffx.runFfxJsonStreaming.getCall(0).args[1], ['log']);
    });

    it('shows the view when the device changes and the view is not visible', async () => {
      let view = fakeWebviewView(
        sandbox, false, new vscode.EventEmitter<any>().event, new vscode.EventEmitter<any>().event);
      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });
      await provider.resetAndShowView(new FuchsiaDevice({ nodename: 'foo' }));
      assert.ok((view as any).show.calledOnce);
    });
  });

  describe('on default target change', () => {
    it('changes the current device and resets the view when visible', () => {
      let view = fakeWebviewView(
        sandbox, true, new vscode.EventEmitter<any>().event, new vscode.EventEmitter<any>().event);
      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });

      targetEventEmitter.fire(new FuchsiaDevice({ nodename: 'bar' }));
      assert.strictEqual(provider.currentTargetDevice, 'bar');

      let webview = view.webview as SinonStubbedInstance<FakeWebview>;
      assert.deepStrictEqual(webview.postMessage.getCall(0).args[0], { type: 'reset' });
    });

    it('changes the current device when the view is not visible', () => {
      let view = fakeWebviewView(
        sandbox, false, new vscode.EventEmitter<any>().event, new vscode.EventEmitter<any>().event);
      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });

      targetEventEmitter.fire(new FuchsiaDevice({ nodename: 'bar' }));
      assert.strictEqual(provider.currentTargetDevice, 'bar');

      let webview = view.webview as SinonStubbedInstance<FakeWebview>;
      assert.ok(!webview.postMessage.calledOnce);
    });

    it('does nothing when the device is the same', async () => {
      let view = fakeWebviewView(
        sandbox, false, new vscode.EventEmitter<any>().event, new vscode.EventEmitter<any>().event);
      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });
      await provider.resetAndShowView(new FuchsiaDevice({ nodename: 'foo' }));

      targetEventEmitter.fire(new FuchsiaDevice({ nodename: 'foo' }));
      assert.strictEqual(provider.currentTargetDevice, 'foo');

      let webview = view.webview as SinonStubbedInstance<FakeWebview>;
      assert.ok(!webview.postMessage.calledOnce);
    });
  });

  describe('when receiving messages from the webview', () => {
    it('handles pause commands and stops the ffx log process', () => {
      let fakeProcess = sandbox.createStubInstance(JsonStreamProcess);
      ffx.runFfxJsonStreaming.returns(fakeProcess);
      let provider = new LoggingViewProvider(uri, ffx);
      let webviewMessagesEmitter = new vscode.EventEmitter<{ command: string }>();
      let view = fakeWebviewView(
        sandbox, true, new vscode.EventEmitter<void>().event, webviewMessagesEmitter.event);

      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });
      assert.ok(ffx.runFfxJsonStreaming.calledOnce);
      assert.ok(fakeProcess.stop.notCalled);

      webviewMessagesEmitter.fire({ command: 'pauseLogStreaming' });

      // No more calls should have happened on runFfxJsonStreaming and the process should have
      // been stopped.
      assert.ok(ffx.runFfxJsonStreaming.calledOnce);
      assert.ok(fakeProcess.stop.calledOnce);
    });

    it('handles resume commands and starts a ffx log process', () => {
      let webviewMessagesEmitter = new vscode.EventEmitter<{ command: string }>();
      let view = fakeWebviewView(
        sandbox, true, new vscode.EventEmitter<any>().event, webviewMessagesEmitter.event);

      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });
      assert.ok(ffx.runFfxJsonStreaming.calledOnce);
      assert.deepStrictEqual(ffx.runFfxJsonStreaming.getCall(0).args[1], ['log']);

      webviewMessagesEmitter.fire({ command: 'resumeLogStreaming' });

      assert.ok(ffx.runFfxJsonStreaming.calledTwice);
      assert.deepStrictEqual(
        ffx.runFfxJsonStreaming.getCall(1).args[1], ['log', '--since', 'now']);
    });

    it('handles getMonotonicTime commands and starts an ffx target get-time process', () => {
      let webviewMessagesEmitter = new vscode.EventEmitter<{ command: string }>();
      let view = fakeWebviewView(
        sandbox, true, new vscode.EventEmitter<any>().event, webviewMessagesEmitter.event);

      provider.resolveWebviewView(view, {
        state: undefined
      }, {
        isCancellationRequested: false,
        onCancellationRequested: sandbox.stub()
      });
      assert.ok(ffx.runFfxJsonStreaming.calledOnce);
      assert.deepStrictEqual(ffx.runFfxJsonStreaming.getCall(0).args[1], ['log']);

      webviewMessagesEmitter.fire({ command: 'getMonotonicTime' });

      assert.ok(ffx.runFfx.calledOnce);
      assert.deepStrictEqual(
        ffx.runFfx.getCall(0).args[0], ['target', 'get-time']);
    });
  });
});

/**
 * Allows to fake the webview.
 *
 * @param sandbox the sinon sandbox backing up the test
 * @param visible  whether the view should be visible or not
 * @param onDidChangeVisibility event fired when the visibility of the view changes
 * @returns  a fake webview
 */
function fakeWebviewView(
  sandbox: SinonSandbox, visible: boolean,
  onDidChangeVisibility: vscode.Event<void>,
  onDidReceiveMessage: vscode.Event<any>,
): vscode.WebviewView {
  let webview = sandbox.createStubInstance(FakeWebview);
  webview.onDidReceiveMessage = onDidReceiveMessage as any;
  webview.postMessage = sandbox.stub();
  webview.asWebviewUri.returns(vscode.Uri.file('/fake/file'));

  let view = <vscode.WebviewView>{ visible };
  // These exist in the WebviewView interface, but when doing
  // `sandbox.stub(view, 'prop')`, sinon claims they don't exist. When attempting to
  // assign directly, tsc correctly complains that they are readonly properties.
  (view as any).onDidChangeVisibility = onDidChangeVisibility;
  (view as any).show = sandbox.stub();
  (view as any).webview = webview;
  return view;
}

class FakeWebview implements vscode.Webview {
  options: vscode.WebviewOptions = <vscode.WebviewOptions>{};
  html: string = '';
  onDidReceiveMessage: vscode.Event<any> = <vscode.Event<any>>{};
  postMessage(message: any): Thenable<boolean> {
    throw new Error('Method not implemented.');
  }
  asWebviewUri(localResource: vscode.Uri): vscode.Uri {
    throw new Error('Method not implemented.');
  }
  cspSource: string = '';
}
