/**
 * updater.js
 *
 * Please use manual update only when it is really required, otherwise please use recommended non-intrusive auto update.
 *
 * Import steps:
 * 1. create `updater.js` for the code snippet
 * 2. require `updater.js` for menu implementation, and set `checkForUpdates` callback from `updater` for the click property of `Check Updates...` MenuItem.
 */
const log = require('electron-log');
const { dialog, ipcMain, app, BrowserWindow } = require('electron');
const { autoUpdater } = require('electron-updater');
const ProgressBar = require('electron-progressbar');
let progressBar = null;
let mainWindow = null;
let i18n = null;
let newVersion = '';
let versionDecription = '';
let isShowProgress = true;
let notificationStyle = 1;

autoUpdater.logger = log;
autoUpdater.logger.transports.file.level = 'info';
autoUpdater.allowDowngrade = true; // 允许降版本升级
autoUpdater.disableDifferentialDownload = true; // 禁用差异化下载
autoUpdater.on('error', (ev, error) => {
  mainWindow.webContents.send('error');
  dialog.showErrorBox(
    'Error: ',
    error == null ? 'unknown' : (error.stack || error).toString()
  );
});

autoUpdater.on('update-available', (ev, info) => {
  mainWindow.webContents.send('update-available',info);
  if (autoUpdater.autoDownload) {
    return;
  }
  if (notificationStyle == 1) {
    dialog.showMessageBox(
      {
        type: 'info',
        title: '版本更新',
        message: '检测到新版本,是否立刻下载?',
        buttons: ['确定', '取消'],
      }).then(function (value){
        if(value.response==0){
          showProgressBar();
          autoUpdater.downloadUpdate();
        }
      });
  } else {
    log.info('autoupdate->update-available');
    mainWindow.webContents.send(
      'update-available',
      newVersion,
      versionDecription
    );
  }
});

autoUpdater.on('update-not-available', (ev, info) => {
  mainWindow.webContents.send('update-not-available',info);
  if (autoUpdater.autoDownload) {
    return;
  }
  if (notificationStyle == 1) {
    dialog.showMessageBox({
      title: '更新提示',
      message: '当前版本已最新',
    });
  } else {
    log.info('autoupdate->update-not-available');
    mainWindow.webContents.send('update-not-available');
  }
});
autoUpdater.on('download-progress', (progressInfo) => {
  log.info('download-progress' + JSON.stringify(progressInfo));
  /**
   * {"bytesPerSecond":17659904,"delta":15347712,"percent":75.84457429617699,"total":46568668,"transferred":35319808}
   */
  if (notificationStyle == '1') {
    progressBar.value = parseFloat(progressInfo.percent.toFixed(1));
  } else {
    mainWindow.webContents.send('download-progress', progressInfo);
  }
});
autoUpdater.on('update-downloaded', () => {
  if (autoUpdater.autoDownload) {
    log.info('autoupdate->update-downloaded quitAndInstall');
    mainWindow.webContents.send('update-downloaded');
    autoUpdater.quitAndInstall();
  } else {
    if (notificationStyle == 2) {
      mainWindow.webContents.send('update-downloaded');
    } else {
      if(progressBar){
        progressBar.close();
        progressBar = null;
      }
      dialog.showMessageBox(
        {
          title: '版本更新',
          message: '安装包下载完成,是否立刻升级?',
          buttons:["确定","取消"]
        }
      ).then(function (value){
        if(value.response==0){
          setImmediate(function (){
            autoUpdater.quitAndInstall();
          });
        }
      });
    }
  }
});
//处理自动更新事件(完整更新)。
ipcMain.on('autoUpdate', function (event, arg) {
  log.info('electron 主进程接收到远程升级指令：' + JSON.stringify(arg));
  mainWindow = BrowserWindow.getFocusedWindow();
  checkForUpdates(
    mainWindow,
    null,
    arg.data.newTerminalAppVersion,
    arg.data.newTerminalAppResUrl,
    arg.data.newTerminalAppDescription,
    arg.isAutoUpdate,
    arg.isShowProgress,
    arg.notificationStyle
  );
});
//处理asar自动更新
ipcMain.on('autoUpdateAsar', function (event, arg) {
  log.info('electron 主进程接收到asar远程升级指令：' + JSON.stringify(arg));
  mainWindow = BrowserWindow.getFocusedWindow();
  AutoUpdate.checkForAsarUpdates(
    mainWindow,
    null,
    arg.data.newTerminalAppVersion,
    arg.data.newTerminalAppResUrl,
    arg.data.newTerminalAppDescription,
    arg.isAutoUpdate,
    arg.isShowProgress,
    arg.notificationStyle
  );
});
/**
 * 确认下载更新
 */
ipcMain.on('confirmDownload', function () {
  if (autoUpdater.autoDownload) {
    return;
  }
  log.info('autoupdate->confirmDownload 触发');
  autoUpdater.downloadUpdate();
});
/**
 * 确认安装更新(必须在下载完成事件触发后才能执行安装)
 */
ipcMain.on('confirmUpdate', function () {
  if (autoUpdater.autoDownload) {
    return;
  }
  autoUpdater.quitAndInstall();
});
/**
 * 检查更新
 * @param {object} mainWindowObj 窗口对象
 * @param {object} i18n vue 根实例,用于实现国际化
 * @param {string} newVersionStr 新版本号
 * @param {string} downloadUrl 版本下载地址
 * @param {string} versionDecriptionStr 版本描述信息
 * @param {boolean} isAutoUpdate 是否自动更新
 * @param {boolean} isShowProgressFlag 是否显示安装包下载进度。
 * @param {notificationMode} 提示弹框风格(1:系统窗口提示 2：自定义窗口提示(通过监听相应事件))
 */
function checkForUpdates(
  mainWindowObj,
  i18nObj,
  newVersionStr,
  downloadUrl,
  versionDecriptionStr,
  isAutoUpdate,
  isShowProgressFlag,
  notificationMode
) {
  mainWindow = mainWindowObj;
  i18n = i18nObj;
  newVersion = newVersionStr;
  versionDecription = versionDecriptionStr;

  isShowProgress = (isShowProgressFlag + '').toLowerCase() == 'true';
  autoUpdater.autoDownload = (isAutoUpdate + '').toLowerCase() == 'true';
  if (
    Object.prototype.toString.call(notificationMode) != '[object Number]' ||
    [1, 2].indexOf(notificationMode) == -1
  ) {
    notificationStyle = 1;
  } else {
    notificationStyle = notificationMode;
  }
  if (Object.prototype.toString.call(downloadUrl) == '[object String]') {
    autoUpdater.setFeedURL(downloadUrl);
  }
  if (notificationStyle == 1 && progressBar == null && isAutoUpdate) {
    showProgressBar();
  }

  log.info(
    'checkForUpdates arguments:' +
      newVersion +
      ',' +
      versionDecription +
      ',' +
      downloadUrl +
      ',' +
      isAutoUpdate +
      ',' +
      isShowProgress +
      ',' +
      notificationStyle
  );
  autoUpdater.checkForUpdates();
}
function showProgressBar() {
  if (progressBar) {
    return;
  }
  progressBar = new ProgressBar({
    indeterminate: false,
    title: '版本升级',
    text: '版本升级',
    detail: '应用正在升级-0%',
    initialValue: 0,
    maxValue: 100,
    style: {
      text: {
        overflow: 'hidden',
      },
    },
    browserWindow: {
      minimizable: false,
      modal: true,
      parent: mainWindow,
    },
  })
    .on('completed', function () {
      //console.info(`completed...`);
      //progressBar.detail = "Task completed. Exiting...";
    })
    .on('aborted', function (value) {
      //console.info(`aborted... ${value}`);
    })
    .on('progress', function (value) {
      progressBar.detail = `应用正在升级-${value}%`;
    });
  progressBar.value = 0;
  mainWindow.focus();
}
/**
 *
 * @param {*} mainWindowObj
 * @param {*} i18nObj
 * @param {*} newVersionStr
 * @param {*} downloadUrl
 * @param {*} versionDecriptionStr
 * @param {*} isAutoUpdate
 * @param {*} isShowProgressFlag
 * @param {*} notificationMode
 */
function checkForAsarUpdates(
  mainWindowObj,
  i18nObj,
  newVersionStr,
  downloadUrl,
  versionDecriptionStr,
  isAutoUpdate,
  isShowProgressFlag,
  notificationMode
) {
  mainWindow = mainWindowObj;
  i18n = i18nObj;
  newVersion = newVersionStr;
  versionDecription = versionDecriptionStr;

  isShowProgress = (isShowProgressFlag + '').toLowerCase() == 'true';
  autoUpdater.autoDownload = (isAutoUpdate + '').toLowerCase() == 'true';
  if (
    Object.prototype.toString.call(notificationMode) != '[object Number]' ||
    [1, 2].indexOf(notificationMode) == -1
  ) {
    notificationStyle = 1;
  } else {
    notificationStyle = notificationMode;
  }
  var url = downloadUrl + '/AsarVersionInfo.json';
  var asarUrl = downloadUrl + '/' + newVersionStr + '.asar';
  log.info(
    '请求asar版本信息文件:' +
      url +
      ',platform=' +
      process.platform +
      ',asarUrl=' +
      asarUrl
  );
  EAU.init({
    api: url,
    asarUrl: asarUrl,
    server: false,
    logFile: 'AsarVersionUpdate.log',
    formatRes: function (versionInfoStr) {
      log.info('AutoUpdate.js->asar版本信息返回:' + versionInfoStr);
      return JSON.parse(versionInfoStr);
    },
  });
  EAU.check(function (error, last, body) {
    if (error) {
      if (error === 'no_update_available') {
        return false;
      }
      dialog.showErrorBox('info', error);
      return false;
    }
    if (isShowProgress) {
      EAU.progress(function (state) {
        // The state is an object that looks like this:
        // {
        //     percent: 0.5,
        //     speed: 554732,
        //     size: {
        //         total: 90044871,
        //         transferred: 27610959
        //     },
        //     time: {
        //         elapsed: 36.235,
        //         remaining: 81.403
        //     }
        // }
        log.info('AutoUpdate.js->asar 下载进度变更：' + JSON.stringify(state));
        mainWindow.webContents.send('asar-download-progress', state);
      });
    }
    mainWindow.webContents.send(
      'asar-update-available',
      newVersionStr,
      versionDecriptionStr
    );
    ipcMain.on('confirmDownloadAsar', function (event, arg) {
      log.info('AutoUpdate.js->收到asar确认更新指令');
      //下载完成回调。
      EAU.download(function (error) {
        if (error) {
          log.info('AutoUpdate.js->asar 下载失败,消息：' + error);
          return false;
        }
        if (process.platform === 'darwin') {
          app.relaunch();
          app.quit();
        } else {
          log.info('AutoUpdate.js->准备退出KT_CPCSS');
          app.quit();
        }
      });
    });
  });
}
module.exports = {
  checkForUpdates: checkForUpdates,
  checkForAsarUpdates: checkForAsarUpdates,
};
