var common = require('../common'),
    hooks = require('../hooks'),
    config = require('../config'),
    diskspace = require('diskspace');

var pyu=config.PYU_START;
var rollLimit = 5;

var ds = -1;
var working = false;

function _cds()
{
    diskspace.check(config.MOUNTPOINT, function(e, result) {
	if(result)
	    ds = Math.round((result.used / result.total) * 100);
	else
	    ds = -1;
	working=false;
    });
}

const loli = require("hashloli");

var lolis = [];
var reqd = [];
loli.defaultConfig.number=3;
loli.defaultConfig.tags = ["-rape"];
loli.defaultConfig.page = 4000;
loli.defaultConfig.range = 20;
const maxLolis = 10;
const maxLolisLong = 100;

function getLoli() {
    if(lolis[0])
	var ret =  lolis.pop();

    if(!ret || lolis.length<maxLolis)
	loli.randomise(function(datas) {
	    if(!datas) return;
	    
	    datas.map(function(vv) {
		let v = vv.file_url;
		
		if(v && !reqd.includes(v)) {
		    lolis.push({file: v, preview: vv.preview_url});
		    reqd.push(v);
		} else if(reqd[0]) reqd.pop();

		while(reqd.length >= maxLolisLong)
		    reqd.pop();

	    });

	    //			console.log("AAAA "+JSON.stringify(lolis));
	});
    return ret;
}
getLoli();
//_cds();

exports.roll_dice = function (frag, post, extra) {
    var ms = frag.split(common.dice_re);
    var dice = [];
    for (var i = 1; i < ms.length && dice.length < rollLimit; i += 2) {
	if (ms[i] == '#loli') {
	    let cute = getLoli();
	    if(cute)
		dice.push([cute.file, cute.preview]);
	    else
		dice.push(["/404", "/s/error.jpg"]);
	}
	else if(ms[i] == '#?')
	{
	    if(!post.body) dice.push([-1]);
	    else {
		var options=[];
		var sbody = post.body.split("\n");
		for(var j=sbody.length-2;j>=0;j--)
		{
		    var cur = sbody[j].trim();
		    if(cur.length<1 || /#\?$/.test(cur)) continue;
		    if(/\?$/.test(cur)) options.push(cur.slice(0,-1));
		    else break;
		}
		var f = options.length;
		if(options.length<1) dice.push([0]);
		else dice.push([options[Math.floor(Math.random() * f)]]);
		
	    }
	}
	else if(ms[i] == '#du')
	{
	    working = true;
	    if( dice.length + (post.dice ? post.dice.length : 0) < rollLimit)
		_cds();
	    else working = false;
	    //	while(working) ; //SPIN SPIN SPINNN~~~~

	    dice.push([ds]);
	}
	else if (ms[i] == '#tea')
	{
	    const hours = new Date().getUTCHours();
	    if ( (hours >= 14 && hours< 16) || (hours >= 2 && hours <4))
		dice.push([true]);
	    else {
		const fxdate = (h) => h<0?fxdate(24+h):h;	    
		const morning_session = fxdate(14 - hours);
		const evening_session = fxdate(2 - hours);
		dice.push([Math.min(morning_session, evening_session)]);
	    }
	}
	else if(ms[i] == '#pyu') {
	    if( dice.length + (post.dice ? post.dice.length : 0) < rollLimit)
		pyu += 1;
	    dice.push([pyu]);
	}
	else if(ms[i] == '#pcount') {
	    dice.push([pyu]);
	}
	else {
	    var info = common.parse_dice(ms[i]);
	    if (!info)
		continue;
	    var f = info.faces;
	    var rolls = [f];
	    for (var j = 0; j < info.n; j++)
		rolls.push(Math.floor(Math.random() * f) + 1);
	    if (info.bias)
		rolls.push({bias: info.bias})
	    dice.push(rolls);
	}
    }
    if (dice.length) {
	// Would prefer an appending scheme for adding new rolls but
	// there's no hash value append redis command...
	// I don't want to spill into a separate redis list.
	// Overwriting the whole log every time is quadratic though.
	// Enforcing a roll limit to deter that and for sanity
	var exist = post.dice ? post.dice.length : 0;
	if (dice.length + exist > rollLimit)
	    dice = dice.slice(0, Math.max(0, rollLimit - exist));
	if (dice.length) {
	    extra.new_dice = dice;
	    dice = post.dice ? post.dice.concat(dice) : dice;
	    post.dice = dice;
	}
    }
};

function inline_dice(post, dice) {
    if (dice && dice.length) {
	dice = JSON.stringify(dice);
	post.dice = dice.substring(1, dice.length - 1);
    }
}

hooks.hook('attachToPost', function (attached, cb) {
    var new_dice = attached.extra.new_dice;
    if (new_dice) {
	attached.attach.dice = new_dice;
	inline_dice(attached.writeKeys, attached.post.dice);
    }
    cb(null);
});

hooks.hook_sync('inlinePost', function (info) {
    inline_dice(info.dest, info.src.dice);
});

hooks.hook_sync('extractPost', function (post) {
    if (!post.dice)
	return;
    try {
	post.dice = JSON.parse('[' + post.dice + ']');
    }
    catch (e) {
	delete post.dice;
    }
});

// This is looking rather boilerplatey

hooks.hook('clientSynced', function (info, cb) {
    var op = info.op, client = info.client;
    if (op) {
	client.db.get_fun(op, function (err, js) {
	    if (err)
		return cb(err);
	    if (js)
		client.send([op, common.EXECUTE_JS, js]);
	    cb(null);
	});
    }
    else
	cb(null);
});

hooks.hook('clientSynced', function (info, cb) {
    var client = info.client;
    client.db.get_banner(function (err, banner) {
	if (err)
	    return cb(err);
	if (!banner)
	    return cb(null);
	var msg = banner.message;
	if (msg)
	    client.send([banner.op, common.UPDATE_BANNER, msg]);
	cb(null);
    });
});
