/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {Component, AfterViewChecked, ViewChild, ElementRef, Input, ChangeDetectorRef} from '@angular/core';

import {ListItem} from '@app/classes/list-item';
import {LogsTableComponent} from '@app/classes/components/logs-table/logs-table-component';
import {ServiceLog} from '@app/classes/models/service-log';
import {LogsContainerService} from '@app/services/logs-container.service';
import {UtilsService} from '@app/services/utils.service';
import {NotificationService} from '@modules/shared/services/notification.service';

export enum ListLayout {
  Table = 'TABLE',
  Flex = 'FLEX'
}

@Component({
  selector: 'service-logs-table',
  templateUrl: './service-logs-table.component.html',
  styleUrls: ['./service-logs-table.component.less']
})
export class ServiceLogsTableComponent extends LogsTableComponent implements AfterViewChecked {

  constructor(
    private logsContainer: LogsContainerService,
    private utils: UtilsService,
    private cdRef: ChangeDetectorRef,
    private notificationService: NotificationService
  ) {
    super();
  }

  ngAfterViewChecked() {
    this.checkListLayout();
    this.cdRef.detectChanges();
  }

  /**
   * The element reference is used to check if the table is broken or not.
   */
  @ViewChild('tableListEl', {
    read: ElementRef
  })
  private tableListElRef: ElementRef;

  /**
   * The element reference is used to check if the table is broken or not.
   */
  @ViewChild('tableWrapperEl', {
    read: ElementRef
  })
  private tableWrapperElRef: ElementRef;

  /**
   * We only show the labels in flex layout when this property is TRUE.
   * @type {boolean}
   */
  @Input()
  showLabels: boolean = false;

  /**
   * The minimum width for the log message column. It is used when we check if the layout is broken or not.
   * @type {number}
   */
  @Input()
  logMessageColumnMinWidth: number = 175;

  /**
   * We use this property in the broken table layout check process when the log message is displayed.
   * @type {string}
   */
  @Input()
  logMessageColumnCssSelector: string = 'tbody tr td.log-message';

  /**
   * Set the layout for the list.
   * It can be:
   * 'TABLE': good for comparison, but it is not useful whe the user wants to display too much fields
   * 'FLEX': flexible layout (with flex box) is good for display lot of column or display the log list on a relative
   * narrow display.
   * @type {Layout}
   */
  @Input()
  layout: ListLayout = ListLayout.Table;

  readonly dateFormat: string = 'dddd, MMMM Do';

  readonly timeFormat: string = 'h:mm:ss A';

  private copyLog = (log: ServiceLog): void => {
    if (document.queryCommandSupported('copy')) {
      const text = log.log_message,
        node = document.createElement('textarea');
      node.value = text;
      Object.assign(node.style, {
        position: 'fixed',
        top: '0',
        left: '0',
        width: '1px',
        height: '1px',
        border: 'none',
        outline: 'none',
        boxShadow: 'none',
        backgroundColor: 'transparent',
        padding: '0'
      });
      document.body.appendChild(node);
      node.select();
      if (document.queryCommandEnabled('copy')) {
        document.execCommand('copy');
        this.notificationService.addNotification({
          type: 'success',
          title: 'logs.copy.title',
          message: 'logs.copy.success'
        });
      } else {
        this.notificationService.addNotification({
          type: 'success',
          title: 'logs.copy.title',
          message: 'logs.copy.failed'
        });
      }
      document.body.removeChild(node);
    } else {
      this.notificationService.addNotification({
        type: 'success',
        title: 'logs.copy.title',
        message: 'logs.copy.notSupported'
      });
    }
  };

  private openLog = (log: ServiceLog): void => {
    this.logsContainer.openServiceLog(log);
  };

  private openContext = (log: ServiceLog): void => {
    this.logsContainer.loadLogContext(log.id, log.host, log.type);
  };

  readonly logActions = [
    {
      label: 'logs.copy',
      iconClass: 'fa fa-files-o',
      onSelect: this.copyLog
    },
    {
      label: 'logs.open',
      iconClass: 'fa fa-external-link',
      onSelect: this.openLog
    },
    {
      label: 'logs.context',
      iconClass: 'fa fa-crosshairs',
      onSelect: this.openContext
    }
  ];

  readonly customStyledColumns: string[] = ['level', 'type', 'logtime', 'log_message', 'path'];

  private readonly messageFilterParameterName: string = 'log_message';

  private readonly logsType: string = 'serviceLogs';

  private selectedText: string = '';

  /**
   * This is a private flag to store the table layout check result. It is used to show user notifications about
   * non-visible information.
   * @type {boolean}
   */
  private tooManyColumnsSelected: boolean = false;

  get contextMenuItems(): ListItem[] {
    return this.logsContainer.queryContextMenuItems;
  }

  get timeZone(): string {
    return this.logsContainer.timeZone;
  }

  get filters(): any {
    return this.logsContainer.filters;
  }

  get logsTypeMapObject(): object {
    return this.logsContainer.logsTypeMap.serviceLogs;
  }

  get isContextMenuDisplayed(): boolean {
    return Boolean(this.selectedText);
  };

  /**
   * 'left' CSS property value for context menu dropdown
   * @type {number}
   */
  contextMenuLeft: number = 0;

  /**
   * 'top' CSS property value for context menu dropdown
   * @type {number}
   */
  contextMenuTop: number = 0;

  isDifferentDates(dateA, dateB): boolean {
    return this.utils.isDifferentDates(dateA, dateB, this.timeZone);
  }

  openMessageContextMenu(event: MouseEvent): void {
    const selectedText = getSelection().toString();
    if (selectedText) {
      this.contextMenuLeft = event.clientX;
      this.contextMenuTop = event.clientY;
      this.selectedText = selectedText;
      event.preventDefault();
    }
  }

  updateQuery(event: ListItem): void {
    this.logsContainer.queryParameterAdd.next({
      name: this.messageFilterParameterName,
      value: this.selectedText,
      isExclude: event.value
    });
  }

  /**
   * Handle the event when the contextual menu component hide itself.
   */
  onContextMenuDismiss(): void {
    this.selectedText = '';
  };

  /**
   * The goal is to check if the log message column is readable or not. Doing this by checking if it is displayed or not
   * and by checking the current width and comparing with the minimum configured width.
   * @returns {boolean}
   */
  isLogMessageVisible(): boolean {
    let visible:boolean = this.isColumnDisplayed('log_message');
    if (this.logs.length && visible && this.layout === ListLayout.Table) {
      const tableElement: HTMLElement = this.tableListElRef.nativeElement;
      const lastTdElement = (tableElement && <HTMLElement>tableElement.querySelectorAll(this.logMessageColumnCssSelector)[0]) || undefined;
      const minWidth = parseFloat(window.getComputedStyle(lastTdElement).minWidth) || this.logMessageColumnMinWidth;
      const lastTdElementInfo = lastTdElement.getBoundingClientRect();
      visible = lastTdElementInfo.width >= minWidth;
    }
    return visible;
  }

  /**
   * Check if the log list (table) fits its container. The goal is to decide if the layout is broken or not.
   * @returns {boolean}
   */
  isLogListFitToTheContainer(): boolean {
    let result = this.layout === ListLayout.Flex;
    if (!result) {
      const tableElement: HTMLElement = this.tableListElRef.nativeElement;
      const tableElementInfo = tableElement.getBoundingClientRect();
      const wrapperElement: HTMLElement = this.tableWrapperElRef.nativeElement;
      const wrapperElementInfo = wrapperElement.getBoundingClientRect();
      result = wrapperElementInfo.width >= tableElementInfo.width;
    }
    return result;
  }

  /**
   * The goal of this function is to check either the log message column is readable if displayed or the all table
   * columns are visible otherwise.
   */
  private checkListLayout(): void {
    this.tooManyColumnsSelected = this.isColumnDisplayed('log_message') ? !this.isLogMessageVisible() : !this.isLogListFitToTheContainer();
  }

  /**
   * The goal is to enable the layout change to the user so that he/she can decide which view is more readable.
   * @param {Layout} layout
   */
  public setLayout(layout: ListLayout): void {
    this.layout = layout;
  }

  /**
   * Find the label for the given field in the @columns ListItem array
   * @param {string} field
   * @returns {string}
   */
  private getLabelForField(field: string): string {
    const column: ListItem = this.columns.find(currentColumn => currentColumn.value === field);
    return column && (column.label || column.value);
  }

  /**
   * Toggle the true/false value of the showLabels property. The goal is to show/hide the labels in the flex box layout,
   * so that the user can decide if he/she wants to see the labels and lost some space.
   */
  private toggleShowLabels(): void {
    this.showLabels = !this.showLabels;
  }

  updateSelectedColumns(columns: string[]): void {
    this.logsContainer.updateSelectedColumns(columns, this.logsType);
  }

}
