{"size": 2500, "ext": "js", "max_stars_repo_path": "Core/CommandLoader.js", "max_stars_repo_name": "Snazzah/PhotoBox", "max_stars_repo_stars_event_min_datetime": "2018-03-14T15:11:41.000Z", "max_stars_repo_stars_event_max_datetime": "2022-01-14T15:24:27.000Z", "max_issues_repo_path": "Core/CommandLoader.js", "max_issues_repo_name": "Tominous/PhotoBox", "max_issues_repo_issues_event_min_datetime": "2018-08-01T14:54:29.000Z", "max_issues_repo_issues_event_max_datetime": "2020-12-04T19:39:19.000Z", "max_forks_repo_path": "Core/CommandLoader.js", "max_forks_repo_name": "Tominous/PhotoBox", "max_forks_repo_forks_event_min_datetime": "2018-08-01T14:43:42.000Z", "max_forks_repo_forks_event_max_datetime": "2020-10-14T08:00:57.000Z"}
{"max_stars_count": 16, "max_issues_count": 7, "max_forks_count": 3, "avg_line_length": 28.4090909091, "max_line_length": 106, "alphanum_fraction": 0.6244}
const fs = require('fs');
const path = require('path');
const logger = require('./Logger')('COMMANDLOADER');

module.exports = class CommandLoader {
  constructor(client, cPath, debug) {
    this.commands = new Map();
    this.path = path.resolve(cPath);
    this.debug = debug;
    this.client = client;
    this.logger = logger;
  }

  iterateFolder(folderPath) {
    const files = fs.readdirSync(folderPath);
    files.map(file => {
      const filePath = path.join(folderPath, file);
      const stat = fs.lstatSync(filePath);
      if(stat.isSymbolicLink()) {
        const realPath = fs.readlinkSync(filePath);
        if(stat.isFile() && file.endsWith('.js')) {
          this.load(realPath);
        }else if(stat.isDirectory()) {
          this.iterateFolder(realPath);
        }
      }else if(stat.isFile() && file.endsWith('.js')) {
        this.load(filePath);
      }else if(stat.isDirectory()) {
        this.iterateFolder(filePath);
      }
    });
  }

  load(commandPath) {
    this.logger.debug('Loading command', commandPath);
    delete require.cache[require.resolve(commandPath)];
    const cls = require(commandPath);
    const cmd = new cls(this.client);
    cmd.path = commandPath;
    this.commands.set(cmd.name, cmd);
    return cmd;
  }

  reload() {
    this.commands.clear();
    this.iterateFolder(this.path);
    logger.info(`Loaded ${this.commands.size} commands.`);
  }

  get(name) {
    let cmd = this.getAbs(name) || null;
    if(cmd) return cmd;
    this.commands.forEach(c => {
      if(c.aliases.includes(name)) cmd = c;
    });
    return cmd;
  }

  getAbs(name) {
    return this.commands.get(name);
  }

  has(name) {
    return !!this.get(name);
  }

  preload(name) {
    if(!this.has(name)) return;
    this.get(name).preload();
  }

  async preloadAll() {
    const preloadedCommands = await Promise.all(Array.from(this.commands.values()).map(c => c.preload()));
    logger.info(`Pre-loaded ${preloadedCommands.filter(c => c !== true).length} commands.`);
  }

  async processCooldown(message, name) {
    if(this.client.owner(message)) return true;
    const command = this.get(name);
    const now = Date.now() - 1;
    const cooldown = command.cooldownAbs;
    let userCD = await this.client.db.hget(`cooldowns:${message.author.id}`, command.name) || 0;
    if(userCD) userCD = parseInt(userCD);
    if(userCD + cooldown > now) return false;
    await this.client.db.hset(`cooldowns:${message.author.id}`, command.name, now);
    return true;
  }
};