// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

import {Isolate} from './model.js';

defineCustomElement('trace-file-reader', (templateText) =>
 class TraceFileReader extends HTMLElement {
  constructor() {
    super();
    const shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.innerHTML = templateText;
    this.addEventListener('click', e => this.handleClick(e));
    this.addEventListener('dragover', e => this.handleDragOver(e));
    this.addEventListener('drop', e => this.handleChange(e));
    this.$('#file').addEventListener('change', e => this.handleChange(e));
    this.$('#fileReader').addEventListener('keydown', e => this.handleKeyEvent(e));
  }

  $(id) {
    return this.shadowRoot.querySelector(id);
  }

  get section() {
    return this.$('#fileReaderSection');
  }

  updateLabel(text) {
    this.$('#label').innerText = text;
  }

  handleKeyEvent(event) {
    if (event.key == "Enter") this.handleClick(event);
  }

  handleClick(event) {
    this.$('#file').click();
  }

  handleChange(event) {
    // Used for drop and file change.
    event.preventDefault();
    var host = event.dataTransfer ? event.dataTransfer : event.target;
    this.readFile(host.files[0]);
  }

  handleDragOver(event) {
    event.preventDefault();
  }

  connectedCallback() {
    this.$('#fileReader').focus();
  }

  readFile(file) {
    if (!file) {
      this.updateLabel('Failed to load file.');
      return;
    }
    this.$('#fileReader').blur();

    this.section.className = 'loading';
    const reader = new FileReader();

    if (['application/gzip', 'application/x-gzip'].includes(file.type)) {
      reader.onload = (e) => {
        try {
          const textResult = pako.inflate(e.target.result, {to: 'string'});
          this.processRawText(file, textResult);
          this.section.className = 'success';
          this.$('#fileReader').classList.add('done');
        } catch (err) {
          console.error(err);
          this.section.className = 'failure';
        }
      };
      // Delay the loading a bit to allow for CSS animations to happen.
      setTimeout(() => reader.readAsArrayBuffer(file), 0);
    } else {
      reader.onload = (e) => {
        try {
          this.processRawText(file, e.target.result);
          this.section.className = 'success';
          this.$('#fileReader').classList.add('done');
        } catch (err) {
          console.error(err);
          this.section.className = 'failure';
        }
      };
      // Delay the loading a bit to allow for CSS animations to happen.
      setTimeout(() => reader.readAsText(file), 0);
    }
  }

  processRawText(file, result) {
    let return_data;
    if (result.includes('V8.GC_Objects_Stats')) {
      return_data = this.createModelFromChromeTraceFile(result);
    } else {
      let contents = result.split('\n');
      return_data = this.createModelFromV8TraceFile(contents);
    }
    this.extendAndSanitizeModel(return_data);
    this.updateLabel('Finished loading \'' + file.name + '\'.');
    this.dispatchEvent(new CustomEvent(
        'change', {bubbles: true, composed: true, detail: return_data}));
  }

  createOrUpdateEntryIfNeeded(data, entry) {
    console.assert(entry.isolate, 'entry should have an isolate');
    if (!(entry.isolate in data)) {
      data[entry.isolate] = new Isolate(entry.isolate);
    }
    const data_object = data[entry.isolate];
    if (('id' in entry) && !(entry.id in data_object.gcs)) {
      data_object.gcs[entry.id] = {non_empty_instance_types: new Set()};
    }
    if ('time' in entry) {
      if (data_object.end === null || data_object.end < entry.time) {
        data_object.end = entry.time;
      }
      if (data_object.start === null || data_object.start > entry.time) {
        data_object.start = entry.time;
      }
    }
  }

  createDatasetIfNeeded(data, entry, data_set) {
    if (!(data_set in data[entry.isolate].gcs[entry.id])) {
      data[entry.isolate].gcs[entry.id][data_set] = {
        instance_type_data: {},
        non_empty_instance_types: new Set(),
        overall: 0
      };
      data[entry.isolate].data_sets.add(data_set);
    }
  }

  addFieldTypeData(data, isolate, gc_id, data_set, tagged_fields,
                   inobject_smi_fields, embedder_fields, unboxed_double_fields,
                   boxed_double_fields, string_data, other_raw_fields) {
    data[isolate].gcs[gc_id][data_set].field_data = {
      tagged_fields,
      inobject_smi_fields,
      embedder_fields,
      unboxed_double_fields,
      boxed_double_fields,
      string_data,
      other_raw_fields
    };
  }

  addInstanceTypeData(data, isolate, gc_id, data_set, instance_type, entry) {
    data[isolate].gcs[gc_id][data_set].instance_type_data[instance_type] = {
      overall: entry.overall,
      count: entry.count,
      histogram: entry.histogram,
      over_allocated: entry.over_allocated,
      over_allocated_histogram: entry.over_allocated_histogram
    };
    data[isolate].gcs[gc_id][data_set].overall += entry.overall;
    if (entry.overall !== 0) {
      data[isolate].gcs[gc_id][data_set].non_empty_instance_types.add(
          instance_type);
      data[isolate].gcs[gc_id].non_empty_instance_types.add(instance_type);
      data[isolate].non_empty_instance_types.add(instance_type);
    }
  }

  extendAndSanitizeModel(data) {
    const checkNonNegativeProperty = (obj, property) => {
      console.assert(obj[property] >= 0, 'negative property', obj, property);
    };

    Object.values(data).forEach(isolate => isolate.finalize());
  }

  createModelFromChromeTraceFile(contents) {
    const data = Object.create(null);  // Final data container.
    const parseOneGCEvent = (actual_data) => {
      Object.keys(actual_data).forEach(data_set => {
        const string_entry = actual_data[data_set];
        try {
          const entry = JSON.parse(string_entry);
          this.createOrUpdateEntryIfNeeded(data, entry);
          this.createDatasetIfNeeded(data, entry, data_set);
          const isolate = entry.isolate;
          const time = entry.time;
          const gc_id = entry.id;
          data[isolate].gcs[gc_id].time = time;

          const field_data = entry.field_data;
          this.addFieldTypeData(data, isolate, gc_id, data_set,
            field_data.tagged_fields,
            field_data.inobject_smi_fields,
            field_data.embedder_fields,
            field_data.unboxed_double_fields,
            field_data.boxed_double_fields,
            field_data.string_data,
            field_data.other_raw_fields);

          data[isolate].gcs[gc_id][data_set].bucket_sizes =
              entry.bucket_sizes;
          for (let [instance_type, value] of Object.entries(
                   entry.type_data)) {
            // Trace file format uses markers that do not have actual
            // properties.
            if (!('overall' in value)) continue;
            this.addInstanceTypeData(
                data, isolate, gc_id, data_set, instance_type, value);
          }
        } catch (e) {
          console.error('Unable to parse data set entry', e);
        }
      });
    };
    console.log(`Processing log as chrome trace file.`);
    try {
      let gc_events_filter = (event) => {
        if (event.name == 'V8.GC_Objects_Stats') {
          parseOneGCEvent(event.args);
        }
        return oboe.drop;
      };

      let oboe_stream = oboe();
      // Trace files support two formats.
      oboe_stream
          // 1) {traceEvents: [ data ]}
          .node('traceEvents.*', gc_events_filter)
          // 2) [ data ]
          .node('!.*', gc_events_filter)
          .fail(() => { throw new Error("Trace data parse failed!"); });
      oboe_stream.emit('data', contents);
    } catch (e) {
      console.error('Unable to parse chrome trace file.', e);
    }
    return data;
  }

  createModelFromV8TraceFile(contents) {
    console.log('Processing log as V8 trace file.');
    contents = contents.map(function(line) {
      try {
        // Strip away a potentially present adb logcat prefix.
        line = line.replace(/^I\/v8\s*\(\d+\):\s+/g, '');
        return JSON.parse(line);
      } catch (e) {
        console.log('Unable to parse line: \'' + line + '\' (' + e + ')');
      }
      return null;
    });

    const data = Object.create(null);  // Final data container.
    for (var entry of contents) {
      if (entry === null || entry.type === undefined) {
        continue;
      }
      if (entry.type === 'zone') {
        this.createOrUpdateEntryIfNeeded(data, entry);
        const stacktrace = ('stacktrace' in entry) ? entry.stacktrace : [];
        data[entry.isolate].samples.zone[entry.time] = {
          allocated: entry.allocated,
          pooled: entry.pooled,
          stacktrace: stacktrace
        };
      } else if (
          entry.type === 'zonecreation' || entry.type === 'zonedestruction') {
        this.createOrUpdateEntryIfNeeded(data, entry);
        data[entry.isolate].zonetags.push(
            Object.assign({opening: entry.type === 'zonecreation'}, entry));
      } else if (entry.type === 'gc_descriptor') {
        this.createOrUpdateEntryIfNeeded(data, entry);
        data[entry.isolate].gcs[entry.id].time = entry.time;
        if ('zone' in entry)
          data[entry.isolate].gcs[entry.id].malloced = entry.zone;
      } else if (entry.type === 'field_data') {
        this.createOrUpdateEntryIfNeeded(data, entry);
        this.createDatasetIfNeeded(data, entry, entry.key);
        this.addFieldTypeData(data, entry.isolate, entry.id, entry.key,
          entry.tagged_fields, entry.embedder_fields, entry.inobject_smi_fields,
          entry.unboxed_double_fields, entry.boxed_double_fields,
          entry.string_data, entry.other_raw_fields);
      } else if (entry.type === 'instance_type_data') {
        if (entry.id in data[entry.isolate].gcs) {
          this.createOrUpdateEntryIfNeeded(data, entry);
          this.createDatasetIfNeeded(data, entry, entry.key);
          this.addInstanceTypeData(
              data, entry.isolate, entry.id, entry.key,
              entry.instance_type_name, entry);
        }
      } else if (entry.type === 'bucket_sizes') {
        if (entry.id in data[entry.isolate].gcs) {
          this.createOrUpdateEntryIfNeeded(data, entry);
          this.createDatasetIfNeeded(data, entry, entry.key);
          data[entry.isolate].gcs[entry.id][entry.key].bucket_sizes =
              entry.sizes;
        }
      } else {
        console.log('Unknown entry type: ' + entry.type);
      }
    }
    return data;
  }
});
