const Constants = require('../../constants');
const fs = require('fs');
const helpers = require('../../helpers');
const os = require('os');
const path = require('path');
const unzip = require('unzipper');

const addListeners = (ipcMain, {getCleanupReleases, standardIPCReply}) => {
  ipcMain.on(Constants.IPC_Check_Installed, (event, data) => {
    const destination = path.join(helpers.getDataDirectory(), data.Version);
    helpers
    .getMissingDependencies(data.Dependencies)
    .then((dependencies) => {
      let exists = false;
      try {
        exists = fs.existsSync(destination) && fs.lstatSync(destination).isDirectory();
      } catch (e) {
      }
      standardIPCReply(event, Constants.IPC_Check_Installed_Reply, {
        Dependencies: dependencies,
        Exists: exists,
        Version: data.Version,
      });
    }).catch(error => {
      standardIPCReply(event, Constants.IPC_Check_Installed_Reply, {
        Dependencies: [],
        Version: data.Version,
      }, error);
    });
  });

  ipcMain.on(Constants.IPC_Cleanup_Releases + '_sync', (event, data) => {
    if (getCleanupReleases()) {
      helpers.cleanupOldReleases(data.version_list);
    }

    event.returnValue = true;
  });

  ipcMain.on(Constants.IPC_Extract_Release, (event, data) => {
    const destination = path.join(helpers.getDataDirectory(), data.Version);
    helpers.removeDirectoryRecursively(destination);
    helpers.mkDirByPathSync(destination);

    const stream = fs.createReadStream(data.Source);
    stream
    .pipe(unzip.Extract({ path: destination }))
    .on('error', error => {
      try {
        helpers.removeDirectoryRecursively(destination);
      } catch (e) {
      }
      stream.close();
      standardIPCReply(event, Constants.IPC_Extract_Release_Complete, {
        Source: data.Source,
      }, error);
    })
    .on('finish', () => {
      stream.close();
      if (os.platform() !== 'win32') {
        helpers
        .executeAndWait("chmod +x \"" + path.join(destination, 'repertory') + "\"")
        .then(() => {
          standardIPCReply(event, Constants.IPC_Extract_Release_Complete, {
            Source: data.Source,
          });
        })
        .catch(error => {
          standardIPCReply(event, Constants.IPC_Extract_Release_Complete, {
            Source: data.Source,
          }, error);
        })
      } else {
        standardIPCReply(event, Constants.IPC_Extract_Release_Complete, {
          Source: data.Source,
        });
      }
    });
  });

  ipcMain.on(Constants.IPC_Test_Release, (event, data) => {
    helpers
    .testRepertoryBinary(data.Version)
    .then(() => {
      standardIPCReply(event, Constants.IPC_Test_Release_Reply, {});
    })
    .catch(error => {
      standardIPCReply(event, Constants.IPC_Test_Release_Reply, {}, error);
    });
  });
};

module.exports = {
  addListeners
};
