import * as monaco from 'monaco-editor';

class LoadTestResultDetailModel {
  constructor() {
    this.testResult = null;
  }

}

class LoadTestResultDetailView {
  constructor(element, model, controller) {
    this.element = element;
    this.editorContainer = document.createElement('div');
    this.editorContainer.style.flex = '1';
    this.element.appendChild(this.editorContainer);

    this.model = model;
    this.controller = controller;
    this.outputEditor = monaco.editor.create(this.editorContainer, {
      value: '',
      automaticLayout: true,
      quickSuggestions: false
    });
  }
}

class LoadTestResultDetailController {
  constructor(element, model) {
    this.element = element;
    this.model = model;
    this.view = new LoadTestResultDetailView(element, model, this);
  }

  showDetail(result) {
    this.view.outputEditor.setValue('');
    console.log(result);
    if (result.request.type === 'TCP') {
      this.logTcpRequest(result.request);
      this.logTcpResponse(result.response);

    } else {
      this.logHttpRequest(result.request);
      this.logHttpResponse(result.response);
    }

  }

  reset(){
    this.view.outputEditor.setValue('');
  }

  appendLog(text) {
    var range = new monaco.Range(this.view.outputEditor.getModel().getLineCount(), 1, this.view.outputEditor.getModel().getLineCount(), 1);
    var id = {major: 1, minor: 1};
    var op = {identifier: id, range: range, text: text + '\n\n', forceMoveMarkers: true};
    this.view.outputEditor.executeEdits('my-source', [op]);
  }


  logHttpRequest(request) {
    console.log({request});
    let log = `[API Request]\n${request.method} ${request.path} HTTP/1.1\n[Request Headers]\n${this.parseRequestHeaders(request.headers)}\n[Request Body]\n${request.requestBody}`;
    this.appendLog(log);
  }

  logTcpRequest(model) {
    console.log(model);
    let log = `[TCP API Request]\n[Request Body]\n${model.requestBody}`;
    this.appendLog(log);
  }


  logHttpResponse(response) {
    console.log({response});
    let log = `[Response]\nHTTP/1.1 ${response.status}\n[Response Headers]\n${this.parseHeaders(response.headers)}\n[Response Body]\n${response.body}\n`;
    this.appendLog(log);
  }

  logTcpResponse(response) {
    console.log({response});
    let log = `[Response]\n${response.body}\n`;
    this.appendLog(log);
  }

  parseRequestHeaders(headers) {
    let parsedHeaders = '';
    headers.forEach(header => {
      if (header.enabled) {
        parsedHeaders += `${header.key}: ${header.value}\n`;
      }
    });

    return parsedHeaders;
  }

  parseHeaders(headers) {
    let parsedHeaders = '';
    headers.forEach(header => {
      parsedHeaders += `${header.key}: ${header.value}\n`;
    });
    return parsedHeaders;
  }

  resizeEditor() {
    //FIXME: 창 크기 변경시 자동으로 editor 크기가 조정되지 않아서, 0으로 강제 변경후 다시 layout() 호출
    this.view.outputEditor.layout({
      width: 0
    });
    this.view.outputEditor.layout({});

  }

  init() {
    this.bindEvents();
  }

  bindEvents() {
    window.addEventListener('resize', this.resizeEditor.bind(this));
  }
}

class LoadTestResultDetail {
  constructor(contextPath, element) {
    this.contextPath = contextPath || '/';
    this.model = new LoadTestResultDetailModel();
    this.controller = new LoadTestResultDetailController(element, this.model);
    this.controller.init();
  }

  showDetail(result) {
    this.controller.showDetail(result);
  }

  reset() {
    this.controller.reset();
  }
}

export default LoadTestResultDetail;
