#! /usr/bin/perl

use strict;
use warnings;

use Data::Dump qw(dump);
use DBI;
use Filter::SQL;

my $ROWS_PER_PAGE = 20;
my $LOOP_COUNT = 1000;
my $PUSH_MODE = $ENV{PUSH_MODE} || undef;

Filter::SQL->dbh(DBI->connect($ENV{DBI} || 'dbi:mysql:test'))
    or die DBI->errstr;

if ($ENV{USER_ID}) {
    my $timeline = fetch_timeline($ENV{USER_ID});
    dump($timeline);
    exit 0;
}

my $l = 0;
while ($l < $LOOP_COUNT) {
    my $uid = int(rand(10000) ** 1.5) + 1;
    next if $uid > 10000;
    fetch_timeline($uid);
    $l++;
}

sub fetch_timeline {
    if ($PUSH_MODE) {
        goto &fetch_timeline_push;
    } elsif ($ENV{USE_PULL2} || undef) {
        goto &fetch_timeline_pull2;
    } else {
        goto &fetch_timeline_pull;
    }
}

sub fetch_timeline_push {
    my ($uid) = @_;
    my @timeline = SELECT message.id,message.user_id,body FROM message
        INNER JOIN mailbox ON message.id=mailbox.message_id
            WHERE mailbox.user_id=$uid
                ORDER BY mailbox.message_id DESC LIMIT $ROWS_PER_PAGE;;
    @timeline = map {
        +{
            mess_id => $_->[0],
            user_id => $_->[1],
            body    => $_->[2],
        }
    } @timeline;
    \@timeline;
}

sub fetch_timeline_pull {
    my ($uid) = @_;
    if ($ENV{MAX_ID}) {
        EXEC CALL fetch_timeline_ids2($uid,$ENV{MAX_ID});;
    } else {
        EXEC CALL fetch_timeline_ids($uid);;
    }
    my @timeline = SELECT message.id,user_id,body FROM message
        INNER JOIN fetch_timeline_tt USING(id)
            ORDER BY message.id DESC LIMIT $ROWS_PER_PAGE;;
    @timeline = map {
        +{
            mess_id => $_->[0],
            user_id => $_->[1],
            body    => $_->[2],
        }
    } @timeline;
    \@timeline;
}

sub fetch_timeline_pull2 {
    my ($uid) = @_;
    my $sql =<<'EOT';
SELECT message.id,message.user_id,message.body FROM message INNER JOIN (
    SELECT t.follower_id,t.max_id,IFNULL(
    (
      SELECT id FROM message WHERE user_id=t.follower_id
      ORDER BY user_id DESC,id DESC LIMIT 20,1
    ),
  0) AS low_id
  FROM (
    SELECT follower_id,(
      SELECT id FROM message WHERE user_id=follower.follower_id
      ORDER BY user_id DESC,id DESC LIMIT 1) AS max_id
    FROM follower WHERE user_id=? ORDER BY max_id DESC LIMIT 20
  ) as t
) as t2 WHERE user_id=follower_id AND low_id<=id
ORDER BY id DESC LIMIT 20
EOT
            ;
    my $rows = Filter::SQL->dbh->selectall_arrayref($sql, {}, $uid);
    my @timeline = @$rows;
    @timeline = map {
        +{
            mess_id => $_->[0],
            user_id => $_->[1],
            body    => $_->[2],
        }
    } @timeline;
    \@timeline;
}
