#!/usr/bin/perl -w

# market_news.pl
# (c) CWZ, LLC

# Publish in-game crypto market news stories

use strict;
use lib '.';
use CWZ;

sub ApplyEFX($);

Exec: {
	# Is it time?  RNG chances increase as more time has elapsed, up to a max of 300 minutes
	my $time_elapsed = qDb_sc("SELECT TIME_TO_SEC(TIMEDIFF(NOW(), ts)) / 60 AS elapsed FROM Crypto_Reel ORDER BY id DESC LIMIT 1");
	int(rand(350)) + 15 < $time_elapsed or die "Not time yet\n";

	# Pull the Crypto_Reel with the story weights JOINed to assess market
	my $recent_reel = qDb_ar("SELECT news_id, wgt FROM Crypto_Reel cr JOIN Crypto_News cn ON cn.id = cr.news_id
									  ORDER BY cr.id DESC LIMIT 10");

	# Quick loop through to see what wgt stories have been recently selected
	# ..set a max_wgt to select from DB depending on results
	my ($num_300, $num_200, $num_100, $max_wgt) = (0, 0, 0, 400);
	foreach ( @$recent_reel ) {
		++$num_300 if ( $_->{wgt} >= 300 && $_->{wgt} < 400 );
		++$num_200 if ( $_->{wgt} >= 200 && $_->{wgt} < 300 );
		++$num_100 if ( $_->{wgt} >= 100 && $_->{wgt} < 200 );
	}
	$max_wgt = 300 if $num_300 > 1;
	$max_wgt = 200 if $num_200 > 3;

	# Pull a new random drug story where wgt less than requirement
	# ..maybe never select one that is in the last 10 once we have more stories
	my ($new_story, $force_wgt);

	# Check if we've bumped up against any limits
$force_wgt = qDb_sc("SELECT
    CASE
        WHEN price_now <= price_min THEN cd
        WHEN price_now >= price_max THEN -cd
        ELSE NULL
    END AS force_wgt
FROM Crypto_Game
WHERE price_now <= price_min OR price_now >= price_max
ORDER BY RAND() LIMIT 1");
	$new_story = qDb_hr("SELECT * FROM Crypto_News WHERE wgt = $force_wgt ORDER BY RAND() LIMIT 1") if $force_wgt;

	# Select a random story if not
	$new_story = qDb_hr("SELECT * FROM Crypto_News WHERE wgt > 10 AND wgt < $max_wgt ORDER BY RAND() LIMIT 1") unless $force_wgt;
	print "Publishing story..\tcd $new_story->{id}\t wgt $new_story->{wgt}\t efx $new_story->{efx}\n";

	# Decode the EFX column and UPDATE DB accordingly
	ApplyEFX($new_story->{efx});

	# Update Crypto_Reel
	qDb_do("INSERT INTO Crypto_Reel VALUES(null, NOW(), $new_story->{id})");
}

sub ApplyEFX($) {
	my ($efx) = @_;

	my @efx = split(/,/, $efx);
	foreach ( @efx ) {
		my ($coin, $fx) = split(/:/);

		if ( $fx =~ /^=(.+)\*(.+)/ ) {
			my $new_base = $1 + (rand() * $2 - ($2 * 0.5));
			print "Setting (with RNG) $coin to $fx\tbase $1\t mod $2\tnew_base $new_base\n";
			qDb_do("UPDATE Crypto_Game SET delta_base = $new_base / 6000 WHERE shortnm = '$coin'");
		} elsif ( $fx =~ /(.+)\*(.+)/ ) {
			my $new_base = $1 + (rand() * $2 - ($2 * 0.5));
			print "Modifying (with RNG) $coin by $fx\tbase $1\t mod $2\tnew_base $new_base\n";
			qDb_do("UPDATE Crypto_Game SET delta_base = delta_base + $new_base / 6000 WHERE shortnm = '$coin'");
		} elsif ( $fx =~ /^=(.+)$/ ) {
			print "Setting $coin to $fx\tbase $1\n";
			qDb_do("UPDATE Crypto_Game SET delta_base = $1 / 6000 WHERE shortnm = '$coin'");
		} elsif ( $fx =~ /(.+)$/ ) {
			print "Modifying $coin by $fx\tbase $1\n";
			qDb_do("UPDATE Crypto_Game SET delta_base = delta_base + $1 / 6000 WHERE shortnm = '$coin'");
		} else {
			print "Something else! $coin by $fx\n";
		}
	}
}
