// 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 constant from '../src/constants';
import {ChildPart, html, LitElement} from 'lit';
import {Directive, directive} from 'lit/directive.js';
import {customElement, property, state} from 'lit/decorators.js';
import { LogField } from '../src/fields';
import {
  formatLogPayload, formatMalformedLog,
  formatTargetMonotonic, messageForEvent
} from '../src/format_log_text';
import { FfxEventData, FfxLogData, LogData } from '../src/log_data';

class AttributeSetter extends Directive {
  update(part: ChildPart, [attributes]: [any]) {
    const domElement = (part.parentNode as Element);
    for (const attr in attributes) {
      const value = attributes[attr];
      domElement.setAttribute(`data-${attr}`, value);
    }
    return this.render(attributes);
  }

  render(_attributes: any) {
    return '';
  }
}
@customElement('log-view-row')
export class LogRow extends LitElement {
  @property({attribute: true, type: Object})
  public log: FfxLogData | undefined = undefined;

  @state()
  private symbolized: string | undefined;
  private fields!: Record<string, any>;
  private dataAttributes!: Record<string, any>;

  constructor(log: FfxLogData, hasPreviousLog: boolean) {
    super();
    this.log = log;
    if (this.log.data.TargetLog !== undefined) {
      this.formatRow(this.log.data.TargetLog);
    } else if (this.log.data.FfxEvent !== undefined) {
      this.formatFfxEventRow(this.log.data.FfxEvent, hasPreviousLog);
    } else if (this.log.data.MalformedTargetLog !== undefined) {
      this.formatMalformedRow(this.log.data.MalformedTargetLog);
    } else if (this.log.data.SymbolizedTargetLog !== undefined) {
      this.symbolized = this.log.data.SymbolizedTargetLog[1];
      this.formatRow(this.log.data.SymbolizedTargetLog[0]);
    } else if (this.log.data.ViewerEvent !== undefined) {
      this.formatViewerEventRow(this.log.data.ViewerEvent);
    }
  }

  createRenderRoot() {
    return this;
  }

  render() {
    const attributeSetter = directive(AttributeSetter);
    return html`
      <div class="log-entry">
        ${attributeSetter(this.dataAttributes)}
        ${Object.keys(constant.LOGS_HEADERS).map(this.htmlForFieldKey.bind(this))}
      </div>`;
  }

  private htmlForFieldKey(fieldKey: string) {
    const content = this.fields[fieldKey] ?? '';
    return html`
      <div
        id="${fieldKey}"
        title="${fieldKey === 'message' ? '' : content}"
        class="log-list-cell${fieldKey === 'message' ? ' msg-cell' : ''}"
      >
        ${content}
      </div>`;
  }

  /**
   * Formats row for Ffx Logs.
   */
  private formatFfxEventRow(event: FfxEventData, hasPreviousLog: boolean) {
    const fields =
      {'moniker': constant.FFX_MONIKER, 'message': messageForEvent(event, hasPreviousLog)};
    this.dataAttributes = fields;
    this.fields = fields;
  }

  /**
   * Formats row for Malformed Logs.
   * @param malformedLog the malformed log to render as a message.
   */
  private formatMalformedRow(malformedLog: string) {
    const fields = {'message': formatMalformedLog(malformedLog)};
    this.dataAttributes = fields;
    this.fields = fields;
  }

  /**
   *  Formats row for an viewer synthesizedd log.
   * @param message  the message to display.
   */
  private formatViewerEventRow(message: string) {
    const fields = {message, moniker: constant.VSCODE_SYNTHETIC_MONIKER};
    this.dataAttributes = fields;
    this.fields = fields;
  }

  /**
   * Formats row for Target Log and Symbolized Logs.
   */
  private formatRow(log: LogData) {
    let fields = {} as Record<string, any>;
    this.dataAttributes = createAttributes(log);

    let header: LogField;
    for (header in constant.LOGS_HEADERS) {
      let field = header.toLowerCase();
      fields[field] = this.getLogCell(log, field);
    }

    this.fields = fields;
  }

  /**
   * Get the field data from a cell in the Log Viewer table.
   *
   * @param logColumn the field data that determines the column of the table.
   * @returns cell element as a string.
   */
  private getLogCell(log: LogData, logColumn: string): string {
    switch (logColumn) {
      case 'timestamp':
        const time = formatTargetMonotonic(log.metadata.timestamp);
        return time;
      case 'pid':
        const pid = log.metadata.pid ?? '';
        return pid.toString();
      case 'tid':
        const tid = log.metadata.tid ?? '';
        return tid.toString();
      case 'moniker':
        return log.moniker;
      case 'tags':
        const tags = (log.metadata.tags ?? []).join(',');
        return tags;
      case 'severity':
        return log.metadata.severity;
      case 'message':
        const msg = this.symbolized ?? formatLogPayload(log['payload']!);
        return msg;
      default:
        return '';
    }
  }
}

const COMPONENT_URL_REGEX =
  /fuchsia-(pkg|boot):\/\/[^\/]*\/(?<package>[^\\]*).*#meta\/(?<manifest>.+\.cmx?)/;

/**
 * Creates a map with the attributes to be placed in `data-*` for each log element.
 * @param data the log data associated with the log element
 * @returns a map of attribute key name to its value.
 */
function createAttributes(data: LogData): Record<string, any> {
  let attrs: Record<string, any> = {
    moniker: data.moniker,
    severity: data.metadata.severity.toLowerCase(),
  };
  if (data.metadata.tags) {
    attrs['tags'] = `${data.metadata.tags.length}`;
    for (let i = 0; i < data.metadata.tags.length; i++) {
      attrs[`tag-${i}`] = data.metadata.tags[i];
    }
  }
  if (data.metadata.pid) {
    attrs['pid'] = data.metadata.pid;
  }
  if (data.metadata.pid) {
    attrs['tid'] = data.metadata.tid;
  }
  const urlResult = COMPONENT_URL_REGEX.exec(data.metadata.component_url);
  if (urlResult) {
    if (urlResult.groups?.package) {
      attrs['package-name'] = urlResult.groups.package;
    }
    if (urlResult.groups?.manifest) {
      attrs['manifest'] = urlResult.groups.manifest;
    }
  }
  if (data.payload.root.message) {
    attrs['message'] = data.payload.root.message.value;
  }
  if (data.payload.root.printf) {
    attrs['message'] = `${data.payload.root.printf} [${data.payload.root.printf.args.join(', ')}]`;
  }
  for (const [key, value] of Object.entries(data.payload.root.keys ?? {})) {
    attrs[`custom-${key}`] = value;
  }
  return attrs;
}
