import { SpadeDataPoint } from "./SpadeDataPoint";
import pako = require('pako');
import { APIQuery } from "./TwilightDataPoints/APIQuery";
import { BenchmarkAppBooted } from "./TwilightDataPoints/BenchmarkAppBooted";
import { BenchmarkCompleteTransition } from "./TwilightDataPoints/BenchmarkCompleteTransition";
import { BenchmarkComponentInteractive } from "./TwilightDataPoints/BenchmarkComponentInteractive";
import { NetworkRequest } from "./TwilightDataPoints/NetworkRequest";
import { Pageview } from "./TwilightDataPoints/Pageview";
import { BenchmarkCustomEvent } from "./TwilightDataPoints/BenchmarkCustomEvent";
import { DesktopAppLoaded } from "./DesktopDataPoints/DesktopAppLoaded";
import { DesktopInstallCompleted } from "./DesktopDataPoints/DesktopInstallCompleted";
import { DesktopVideoFirstFrame } from "./DesktopDataPoints/DesktopVideoFirstFrame";
import { DesktopPageLoad } from "./DesktopDataPoints/DesktopPageLoad";
import { MobileDataPoint } from "./MobileDataPoint";

export class SpadeEvent {
  uuid: string;
  version: number;
  dataPoints: SpadeDataPoint[] = [];
  createdAt: Date;

  constructor(encodedData: string) {
    const data = JSON.parse(new Buffer(encodedData, 'base64').toString('ascii'));
    this.createdAt = data.CreatedAt;
    this.uuid = data.UUID;
    this.version = data.Version;

    this.populateDataPoints(data.Data);
  }

  populateDataPoints(rawData: string): void {
    let data = pako.inflate(new Buffer(rawData, 'base64').slice(1), { windowBits: -15, to: 'string' });
    for (let dataPoint of JSON.parse(data)) {
      switch (dataPoint.Name) {
        case 'benchmark_api_query':
          this.dataPoints.push(new APIQuery(dataPoint.Fields));
          break;
        case 'benchmark_app_booted':
          this.dataPoints.push(new BenchmarkAppBooted(dataPoint.Fields));
          break;
        case 'benchmark_complete_transition':
          this.dataPoints.push(new BenchmarkCompleteTransition(dataPoint.Fields));
          break;
        case 'benchmark_component_interactive':
          this.dataPoints.push(new BenchmarkComponentInteractive(dataPoint.Fields));
          break;
        case 'benchmark_custom_event':
          if (dataPoint.Fields.duration && +dataPoint.Fields.duration > 0) {
              if (dataPoint.Fields.key !== 'first-cue' && dataPoint.Fields.client_app === 'twilight' &&
                 !dataPoint.Fields.page_component_name ) {
                break;
              }
              this.dataPoints.push(new BenchmarkCustomEvent(dataPoint.Fields));
          }
          break;
        case 'network_request':
          this.dataPoints.push(new NetworkRequest(dataPoint.Fields));
          break;
        case 'pageview':
          this.dataPoints.push(new Pageview(dataPoint.Fields));
          break;
        case 'curse_perf_startup_item':
          this.dataPoints.push(new DesktopAppLoaded(dataPoint.Fields));
          break;
        case 'curse_installer_install_completed':
          this.dataPoints.push(new DesktopInstallCompleted(dataPoint.Fields));
          break;
        case 'curse_perf_page_load':
          this.dataPoints.push(new DesktopPageLoad(dataPoint.Fields));
          break;
        case 'curse_perf_video_first_frame':
          this.dataPoints.push(new DesktopVideoFirstFrame(dataPoint.Fields));
          break;
        case 'mobile_latency_event':
          this.dataPoints.push(new MobileDataPoint(dataPoint.Fields));
          break;
        default:
          console.log(`No implementation for ${dataPoint.Name}. \nFields: ${JSON.stringify(dataPoint.Fields, null, 2)}`);
      }
    }
  }
}
