text: /**
   * MIT License
   *
   * Copyright (c) 2022 FoxxoSnoot
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in all
   * copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   * SOFTWARE.
   */
  
  const axios = require('axios');
  const sleep = require('util').promisify(setTimeout);
  const { randomBytes } = require('crypto');
  const { join } = require('path');
  const { existsSync, mkdirSync, writeFileSync, readFileSync, createWriteStream } = require('fs');
  const { DATA_DIRECTORY, COOKIES_FILE, THUMBNAILS_DIRECTORY, DOWNLOAD_THUMBNAILS } = require('./globals');
  var { CSRF_TOKEN, RESERVED_COOKIES, INVALID_COOKIES, CACHED_AVATARS } = require('./globals');
  
  var helpers = {};
  
  helpers.init = () => {
  	if (!existsSync(DATA_DIRECTORY))
  		mkdirSync(DATA_DIRECTORY);
  	
  	if (!existsSync(join(DATA_DIRECTORY, COOKIES_FILE)))
  		writeFileSync(join(DATA_DIRECTORY, COOKIES_FILE), '');
  	
  	if (DOWNLOAD_THUMBNAILS && !existsSync(THUMBNAILS_DIRECTORY))
  		mkdirSync(THUMBNAILS_DIRECTORY);
  };
  
  axios.interceptors.response.use(undefined, (error) => {
  	if (error.isAxiosError) {
  		if (!error.response && !error.config)
  			return axios.request(error.config);
  		
  		if (error.response.status === 403 && error.response.headers['x-csrf-token'] && error.config) {
  			error.config.headers['x-csrf-token'] = error.response.headers['x-csrf-token'];
  			CSRF_TOKEN = error.response.headers['x-csrf-token'];
  			
  			return axios.request(error.config)
  		} else if (error.response.status === 429 || error.response.status >= 500) {
  			return sleep(500).then(() => axios.request(error.config));
  		}
  	}
  	
  	return Promise.reject(error);
  });
  
  helpers.sleep = sleep;
  helpers.axios = axios;
  
  helpers.shuffle = (array) => {
  	let currentIndex = array.length, temporaryValue, randomIndex;
  	
  	while (0 !== currentIndex) {
  		randomIndex = Math.floor(Math.random() * currentIndex);
  		currentIndex -= 1;
  		
  		temporaryValue = array[currentIndex];
  		array[currentIndex] = array[randomIndex];
  		array[randomIndex] = temporaryValue;
  	}
  	
  	return array;
  };
  
  helpers.getRandomCookie = () => {
  	let cookies = readFileSync(join(DATA_DIRECTORY, COOKIES_FILE)).toString().replace(/\r/g, '').split('\n');
  	let cookie;
  	
  	while (!cookie) {
  		cookies = helpers.shuffle(cookies);
  		
  		if (!RESERVED_COOKIES.includes(cookies[0]) && !INVALID_COOKIES.includes(cookies[0]))
  			cookie = cookies[0];
  	}
  	
  	return cookie;
  };
  
  helpers.downloadThumbnail = (url) => {
  	let filename = randomBytes(50).toString('hex') + '.png';
  	let error = false;
  	
  	axios.get(url, { responseType: 'stream' })
  		.then((response) => response.data.pipe(createWriteStream(join(THUMBNAILS_DIRECTORY, filename))))
  		.catch(() => error = true);
  	
  	if (!error)
  		return filename;
  };
  
  module.exports = helpers;