text: import {
  	Base,
  	ProgressStep,
  	Selection,
  	SelectionUser
  } from 'meteor/rocketchat:importer';
  
  export class SlackUsersImporter extends Base {
  	constructor(info) {
  		super(info);
  
  		this.csvParser = Npm.require('csv-parse/lib/sync');
  		this.userMap = new Map();
  		this.admins = []; //Array of ids of the users which are admins
  	}
  
  	prepare(dataURI, sentContentType, fileName) {
  		super.prepare(dataURI, sentContentType, fileName, true);
  
  		super.updateProgress(ProgressStep.PREPARING_USERS);
  		const uriResult = RocketChatFile.dataURIParse(dataURI);
  		const buf = new Buffer(uriResult.image, 'base64');
  		const parsed = this.csvParser(buf.toString());
  
  		parsed.forEach((user, index) => {
  			// Ignore the first column
  			if (index === 0) {
  				return;
  			}
  
  			const id = Random.id();
  			const username = user[0];
  			const email = user[1];
  			let isBot = false;
  			let isDeleted = false;
  
  			switch (user[2]) {
  				case 'Admin':
  					this.admins.push(id);
  					break;
  				case 'Bot':
  					isBot = true;
  					break;
  				case 'Deactivated':
  					isDeleted = true;
  					break;
  			}
  
  			this.userMap.set(id, new SelectionUser(id, username, email, isDeleted, isBot, true));
  		});
  
  		const userArray = Array.from(this.userMap.values());
  
  		const usersId = this.collection.insert({ 'import': this.importRecord._id, 'importer': this.name, 'type': 'users', 'users': userArray });
  		this.users = this.collection.findOne(usersId);
  		super.updateRecord({ 'count.users': this.userMap.size });
  		super.addCountToTotal(this.userMap.size);
  
  		if (this.userMap.size === 0) {
  			this.logger.error('No users found in the import file.');
  			super.updateProgress(ProgressStep.ERROR);
  			return super.getProgress();
  		}
  
  		super.updateProgress(ProgressStep.USER_SELECTION);
  		return new Selection(this.name, userArray, [], 0);
  	}
  
  	startImport(importSelection) {
  		super.startImport(importSelection);
  		const started = Date.now();
  
  		for (const user of importSelection.users) {
  			const u = this.userMap.get(user.user_id);
  			u.do_import = user.do_import;
  
  			this.userMap.set(user.user_id, u);
  		}
  		this.collection.update({ _id: this.users._id }, { $set: { 'users': Array.from(this.userMap.values()) }});
  
  		const startedByUserId = Meteor.userId();
  		Meteor.defer(() => {
  			super.updateProgress(ProgressStep.IMPORTING_USERS);
  
  			for (const u of this.users.users) {
  				if (!u.do_import) {
  					continue;
  				}
  
  				Meteor.runAsUser(startedByUserId, () => {
  					const existantUser = RocketChat.models.Users.findOneByEmailAddress(u.email) || RocketChat.models.Users.findOneByUsername(u.username);
  
  					let userId = existantUser._id;
  					if (existantUser) {
  						//since we have an existing user, let's try a few things
  						u.rocketId = existantUser._id;
  						RocketChat.models.Users.update({ _id: u.rocketId }, { $addToSet: { importIds: u.id } });
  
  						RocketChat.models.Users.setEmail(existantUser._id, u.email);
  						RocketChat.models.Users.setEmailVerified(existantUser._id, u.email);
  					} else {
  						userId = Accounts.createUser({ username: u.username + Random.id(), password: Date.now() + u.name + u.email.toUpperCase() });
  
  						if (!userId) {
  							console.warn('An error happened while creating a user.');
  							return;
  						}
  
  						Meteor.runAsUser(userId, () => {
  							Meteor.call('setUsername', u.username, {joinDefaultChannelsSilenced: true});
  							RocketChat.models.Users.setName(userId, u.name);
  							RocketChat.models.Users.update({ _id: userId }, { $addToSet: { importIds: u.id } });
  							RocketChat.models.Users.setEmail(userId, u.email);
  							RocketChat.models.Users.setEmailVerified(userId, u.email);
  							u.rocketId = userId;
  						});
  					}
  
  					if (this.admins.includes(u.user_id)) {
  						Meteor.call('setAdminStatus', userId, true);
  					}
  
  					super.addCountCompleted(1);
  				});
  			}
  
  			super.updateProgress(ProgressStep.FINISHING);
  			super.updateProgress(ProgressStep.DONE);
  			const timeTook = Date.now() - started;
  			this.logger.log(`Slack Users Import took ${ timeTook } milliseconds.`);
  		});
  
  		return super.getProgress();
  	}
  }
  