/* eslint-disable no-console */
import async from 'async';
import { promisify } from 'util';
import redis from 'redis';

const client = redis.createClient({
  'host': '127.0.0.1',
  'port': '6379', prefix: '_nuxt_cache_',
});

function hashCode(s: string) {
  let h;
  for(let i = 0; i < s.length; i++) {
    h = Math.imul(31, h) + s.charCodeAt(i) | 0;
  }
  return String(h);
}

client
  .on('connect', () => console.log('info', '[redis-cache] connected'))
  .on('reconnecting', () => console.log('info', '[redis-cache] reconnecting'))
  .on('end', () => console.log('warn', '[redis-cache] disconnected'))
  .on('warning', (msg) => console.log('warn', msg))
  .on('error', (err) => console.error(err));

const get = promisify(client.get).bind(client);
const set = promisify(client.set).bind(client);
const unlink = promisify(client.unlink).bind(client);
const rpush = promisify(client.rpush).bind(client);
const lrange = promisify(client.lrange).bind(client);
const scan = promisify(client.scan).bind(client);

async function init() {
  await set(`g1-${hashCode('test1')}`, 'some value');
  await set(`g2-${hashCode('test2')}`, 'some value');
  await set(`g3-${hashCode('test3')}`, 'some value');
  await set(`g4-${hashCode('test4')}`, 'some value');
  await set(`g5-${hashCode('test5')}`, 'some value');
  await rpush(hashCode('test'), `g1-${hashCode('test1')}`);
  await rpush(hashCode('test'), `g1-${hashCode('test1')}`);
  await rpush(hashCode('test'), `g1-${hashCode('test1')}`);
  await rpush(hashCode('test'), `g1-${hashCode('test1')}`);
  await rpush(hashCode('test'), `g2-${hashCode('test2')}`);
  await rpush(hashCode('test'), `g3-${hashCode('test3')}`);
  await rpush(hashCode('test'), `g4-${hashCode('test4')}`);
  await rpush(hashCode('test'), `g5-${hashCode('test5')}`);

  const keys = await lrange(hashCode('test'), 0, -1);

  console.log({ keys });

  const batchKeys = keys.reduce((a, c) => {
    if (Array.isArray(a[a.length - 1]) && a[a.length - 1].length < 2) {
      a[a.length - 1].push(c);
    } else if (!Array.isArray(a[a.length - 1]) || a[a.length - 1].length >= 2) {
      a.push([c]);
    }
    return a;
  }, []);

  console.log({ batchKeys });

  await new Promise((resolve, reject) => {
    async.eachOfLimit(batchKeys, 10, async.asyncify(async (batch) => {
      return unlink(batch);
    }), (err) => err ? reject(err) : resolve());
  });

  await get(`g1-${hashCode('test1')}`).then(console.log);

  return get(`g1-${hashCode('test1')}`);
}

init()
  .then((res) => {
    console.log({ res });
    process.exit(0);
  })
  .catch((err) => {
  console.error(err);
  process.exit(1);
});
