import { Buffer } from 'buffer';
import { extensions, WorkspaceConfiguration } from 'vscode';
import TelemetryReporter from 'vscode-extension-telemetry';
import { userInfo } from 'os';
import { sep } from 'path';

export class Reporter {
  private reporter: TelemetryReporter;
  private timeOpened: number;
  private lastStackTrace: string;
  numRuns: number;
  numInterruptedRuns: number;
  execTime: number;
  totalPyTime: number;
  totalTime: number;
  pythonVersion: string;

  constructor(private enabled: boolean) {
    const extensionId = 'frenya.vscode-recall';
    const extension = extensions.getExtension(extensionId)!;
    const extensionVersion = extension.packageJSON.version;

    // following key just allows you to send events to azure insights API
    // so it does not need to be protected
    // but obfuscating anyways - bots scan github for keys, but if you want my key you better work for it, damnit!
    const innocentKitten = Buffer.from(
      'NmE3YmNjOTYtZjVmYi00NDIwLTgyZjktYzRhNDUxNzhiMGE2',
      'base64',
    ).toString();

    this.reporter = new TelemetryReporter(extensionId, extensionVersion, innocentKitten);
    this.resetMeasurements();
  }

  sendError(error: Error, code: number = 0, category = 'typescript') {
    console.error(`${category} error: ${error.name} code ${code}\n${error.stack}`);
    if (this.enabled) {
      error.stack = this.anonymizePaths(error.stack);

      // no point in sending same error twice (and we want to stay under free API limit)
      if (error.stack === this.lastStackTrace) return;

      this.reporter.sendTelemetryException(error, {
        code: code.toString(),
        category,
      });

      this.lastStackTrace = error.stack;
    }
  }

  commandWrapper(cmdName: string, cmdHandler: Function) {
    const reporter = this.reporter;
    return function (...args) {
      reporter.sendTelemetryEvent(cmdName);
      return cmdHandler(...args);
    };
  }

  sendEvent(event: string) {
    this.reporter.sendTelemetryEvent(event);
  }

  private resetMeasurements() {
    this.timeOpened = Date.now();

    this.numRuns = 0;
    this.numInterruptedRuns = 0;
    this.execTime = 0;
    this.totalPyTime = 0;
    this.totalTime = 0;
  }

  /**
   * replace username with anon
   */
  anonymizePaths(input: string) {
    // tslint:disable-next-line:triple-equals
    if (input == null) return input;
    return input.replace(new RegExp('\\' + sep + userInfo().username, 'g'), sep + 'anon');
  }

  dispose() {
    this.reporter.dispose();
  }
}

export default Reporter as typeof Reporter;