// 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 chai from 'chai'; // not esm
import chaiDom from 'chai-dom'; // not esm
import * as constant from '../src/constants';
import { FakeWebviewAPi, ffxEventForTest, logDataForTest, malformedLogForTest }
  from './util';
import { Filter } from '../src/filter';
import { LogList, WRAP_LOG_TEXT_ATTR } from '../components/log_list';
import { State } from '../src/state';
import {LitElement} from 'lit';

before(function () {
  chai.should();
  chai.use(chaiDom);
});

describe('LogList', () => {
  let root: HTMLElement;
  let state: State;

  beforeEach(() => {
    root = document.createElement('div');
    document.body.appendChild(root);
    state = new State(new FakeWebviewAPi());
  });

  afterEach(() => {
    root.remove();
  });

  describe('#constructor', () => {
    it('crates a new empty view', async () => {
      const logsList = new LogList(state);
      root.appendChild(logsList.element);
      logsList.element.children.length.should.equal(1);
      await (logsList.element.children[0] as LitElement).updateComplete;
      logsList.element.children[0].nodeName.should.equal('LOG-HEADER');
      logsList.element.should.have.attr('aria-colcount');
      const expectedColumns = Object.keys(state.currentFields).length;
      logsList.element.getAttribute('aria-colcount')?.should.equal(`${expectedColumns}`);
    });

    it('sets the log wrapping from the state', () => {
      state.shouldWrapLogs = true;
      let logList = new LogList(state);
      logList.element.hasAttribute(WRAP_LOG_TEXT_ATTR).should.be.true;

      state.shouldWrapLogs = false;
      logList = new LogList(state);
      logList.element.hasAttribute(WRAP_LOG_TEXT_ATTR).should.be.false;
    });
  });

  describe('#addLog', () => {
    it('appends a log', async () => {
      const view = new LogList(state);
      const logsList = view.element;
      document.body.appendChild(logsList);

      logsList.children.length.should.equal(1);
      await (logsList.children[0] as LitElement).updateComplete;
      logsList.children[0].nodeName.should.equal('LOG-HEADER');
      view.addLog(logDataForTest('core/foo'));
      logsList.children.length.should.equal(2);

      const logLine = logsList.children[1] as LitElement;
      await logLine.updateComplete;
      logLine.children[0].should.have.class('log-entry');
      logLine.children[0].should.have.attr('data-moniker', 'core/foo');
      logLine.children[0].should.have.attr('data-pid', '123');
      logLine.children[0].should.have.attr('data-tid', '456');
      (logLine.children[0] as HTMLElement).hidden.should.be.false;

      const testFields = ['000000.12', '123', '456', 'core/foo', 'my_tag', 'Info', 'msg'];
      let field: keyof typeof testFields;
      for (field in testFields) {
        const logField = logLine.children[0].children[field] as HTMLElement;
        logField.innerText.should.equal(testFields[field]);
      }
      logsList.remove();
    });


    it('hides the log if the filters require so', () => {
      const view = new LogList(state);

      state.registerFilter(new Filter({
        category: 'moniker',
        subCategory: undefined,
        operator: 'contains',
        value: 'core/bar',
      }), 'moniker:core/bar');

      view.addLog(logDataForTest('core/foo'));

      const logsList = view.element;
      logsList.children.length.should.equal(2);
      const logLine = logsList.children[1] as HTMLElement;
      logLine.hidden.should.be.true;
    });

    it('handles ffx events', async () => {
      const view = new LogList(state);
      let moniker = constant.FFX_MONIKER;
      const msg = 'Logger lost connection to target. Retrying...';
      view.addLog(ffxEventForTest('TargetDisconnected'));

      const logsList = view.element;
      document.body.appendChild(logsList);
      logsList.children.length.should.equal(2);
      await (logsList.children[0] as LitElement).updateComplete;
      logsList.children[0].nodeName.should.equal('LOG-HEADER');

      const logLine = logsList.children[1] as LitElement;
      await logLine.updateComplete;

      logLine.children[0].children.length.should.equal(7);
      logLine.children[0].should.have.class('log-entry');
      logLine.children[0].should.have.attr('data-moniker', '<ffx>');
      (logLine.children[0] as HTMLElement).hidden.should.be.false;

      let monikerEl = logLine.children[0].children[3] as HTMLElement;
      let msgEl = logLine.children[0].children[6] as HTMLElement;
      monikerEl.innerText.should.equal(moniker);
      msgEl.innerText.should.equal(msg);
      logsList.remove();
    });

    it('handles malformed logs', async () => {
      const view = new LogList(state);
      const msg = 'Malformed target log: oh no something went wrong';
      view.addLog(malformedLogForTest('oh no something went wrong'));

      const logsList = view.element;
      document.body.appendChild(logsList);
      logsList.children.length.should.equal(2);
      await (logsList.children[0] as LitElement).updateComplete;
      logsList.children[0].nodeName.should.equal('LOG-HEADER');

      const logLine = logsList.children[1] as LitElement;
      await logLine.updateComplete;
      logLine.children[0].children.length.should.equal(7);
      logLine.children[0].should.have.class('log-entry');
      (logLine.children[0] as HTMLElement).hidden.should.be.false;
      let msgEl = logLine.children[0].children[6] as HTMLElement;
      msgEl.innerText.should.equal(msg);
      logsList.remove();
    });

    it('detects user hovering logs', () => {
      const view = new LogList(state);
      view.addLog(logDataForTest('core/foo'));
      const scrollArea = view.element.parentElement;
      scrollArea?.matches(':hover').should.equal(false);
      scrollArea?.dispatchEvent(new MouseEvent('onmouseenter'));
      scrollArea?.matches(':hover').should.equal(true);
    });
  });

  describe('#reset', () => {
    it('resets the log list', () => {
      const view = new LogList(state);
      view.addLog(logDataForTest('core/foo'));

      let logsList = view.element;
      logsList.children.length.should.equal(2);
      view.reset();
      logsList.children.length.should.equal(1);
    });
  });
});
