import * as deprecate from '@electron/internal/common/deprecate';

import { app } from 'electron/main';

const binding = process._linkedBinding('electron_browser_crash_reporter');

class CrashReporter implements Electron.CrashReporter {
  start(options: Electron.CrashReporterStartOptions) {
    const {
      productName = app.name,
      companyName,
      extra = {},
      globalExtra = {},
      ignoreSystemCrashHandler = false,
      submitURL = '',
      uploadToServer = true,
      rateLimit = false,
      compress = true
    } = options || {};

    if (uploadToServer && !submitURL) throw new Error('submitURL must be specified when uploadToServer is true');

    if (!compress && uploadToServer) {
      deprecate.log(
        'Sending uncompressed crash reports is deprecated and will be removed in a future version of Electron. Set { compress: true } to opt-in to the new behavior. Crash reports will be uploaded gzipped, which most crash reporting servers support.'
      );
    }

    const appVersion = app.getVersion();

    if (companyName && globalExtra._companyName == null) globalExtra._companyName = companyName;

    const globalExtraAmended = {
      _productName: productName,
      _version: appVersion,
      ...globalExtra
    };

    binding.start(
      submitURL,
      uploadToServer,
      ignoreSystemCrashHandler,
      rateLimit,
      compress,
      globalExtraAmended,
      extra,
      false
    );
  }

  getLastCrashReport() {
    const reports = this.getUploadedReports().sort((a, b) => {
      const ats = a && a.date ? new Date(a.date).getTime() : 0;
      const bts = b && b.date ? new Date(b.date).getTime() : 0;
      return bts - ats;
    });

    return reports.length > 0 ? reports[0] : null;
  }

  getUploadedReports(): Electron.CrashReport[] {
    return binding.getUploadedReports();
  }

  getUploadToServer() {
    if (process.type === 'browser') {
      return binding.getUploadToServer();
    } else {
      throw new Error('getUploadToServer can only be called from the main process');
    }
  }

  setUploadToServer(uploadToServer: boolean) {
    if (process.type === 'browser') {
      return binding.setUploadToServer(uploadToServer);
    } else {
      throw new Error('setUploadToServer can only be called from the main process');
    }
  }

  addExtraParameter(key: string, value: string) {
    binding.addExtraParameter(key, value);
  }

  removeExtraParameter(key: string) {
    binding.removeExtraParameter(key);
  }

  getParameters() {
    return binding.getParameters();
  }
}

export default new CrashReporter();
