import { Component, Input, OnChanges, OnInit, ViewChild } from '@angular/core';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';

interface IlogLine {
  date?: string;
  level?: string;
  message: string;
}

@Component({
  selector: 'app-log-file-viewer',
  templateUrl: './log-file-viewer.component.html',
  styleUrls: ['./log-file-viewer.component.scss']
})
export class LogFileViewerComponent implements OnInit, OnChanges {
  @Input() log: string;
  logLines: string[];
  splitLogLines = new Map();
  maxLineNoDigits: number;

  @ViewChild('virtualScroll') virtualScroll: CdkVirtualScrollViewport;

  constructor() {
  }

  updateLogLines() {
    if (this.log) {
      this.logLines = this.log.split('\n');
      this.maxLineNoDigits = Math.ceil(Math.log10(this.logLines.length) + 1);
      this.splitLogLines = new Map();
      if (this.virtualScroll) {
        this.virtualScroll.scrollToIndex(this.logLines.length - 1);
      }
    }
  }

  ngOnInit(): void {
    this.updateLogLines();
  }

  ngOnChanges() {
    this.updateLogLines();
  }

  splitLine(line: string): IlogLine {
    if (line.startsWith('[')) {
      const dateStr = line.substring(1, line.indexOf(']'));
      line = line.substring(dateStr.length + 2);
      const levelStr = line.substring(1, line.indexOf(']'));
      line = line.substring(levelStr.length + 2).trim();
      if (Date.parse(dateStr.split(' ')[0])) {
        return {
          date: dateStr,
          level: levelStr,
          message: line,
        };
      }
    } else {
      const parts = line.split(' ');
      if (Date.parse(parts[0])) {
        return {
          date: [parts[0], parts[1]].join(' '),
          level: parts[2],
          message: parts.splice(3).join(' '),
        };
      }
    }


    return {
      message: line,
    };
  }

  getLine(index: number): IlogLine {
    let splitLogLine = this.splitLogLines[index];
    if (!splitLogLine) {
      splitLogLine = this.splitLine(this.logLines[index]);
      this.splitLogLines[index] = splitLogLine;
    }

    return splitLogLine;
  }
}
