#!/usr/bin/perl

use strict;
use warnings;
use open ':std', ':encoding(UTF-8)';

use Parallel::ForkManager;
use Term::ANSIColor qw(:constants);
use List::MoreUtils qw(first_index);
use Digest::MD5 qw(md5 md5_hex md5_base64);

use lib '/app/tools/common/lib';
use Common::Session;
use Common::DB::Diff::Table;

my ( $opt, $usage ) = clopt(
    [ 'help|?|h'     => 'print usage message and exit' ],
    [ 'database|d=s' => 'Database to fix' ],
    [ 'dryrun'       => 'Just dump the primary db dont import' ],
    [ 'primary|p=s'  => 'Primary or source database : db01',      { 'default' => 'db01' } ],
    [ 'replica|r=s'  => 'Replica or destination database : db02', { 'default' => 'db02' } ],
    [ 'table|t=s'    => 'Table to fix' ],
);

if ( defined $opt->table and not defined $opt->database ) {
    logMessag( 'fatal', "Option table requires option database" );
    exit 1;
}

my $primary = $opt->primary;
my $replica = $opt->replica;

my $p_dbh = Common::Session::getdbh($primary);
my $r_dbh = Common::Session::getdbh($replica);

my $dbx = Common::Session::getdbx('admindb');

## get all database diffs
my $search = { 'is_diff' => 'Y' };
if ( defined $opt->database ) {
    $search->{'dbname'} = $opt->database;
    if ( defined $opt->table ) {
        $search->{'tabname'} = $opt->table;
    }
}

my $rset = $dbx->resultset('Report::SysDbReplicaDiff')->search($search);
while ( my $row = $rset->next ) {
    ## next if not $row->message =~ m/.*primary has more.*/i;

    my $db    = $row->dbname;
    my $tab   = $row->tabname;
    my $key   = $row->keycol;
    my $phost = $primary;
    my $min   = $row->minrow;
    my $max   = $row->maxrow;

    my $outfile = "/tmp/${db}_${tab}_missing_rows_${min}_${max}.sql";

    my $dump    = "mysqldump -h $phost --insert-ignore --no-create-info $db $tab --where=\"$key between $min and $max\"";
    my $dumpout = runlogcmd("$dump >$outfile");

    if ( not defined $opt->dryrun ) {
        my $imp    = ("mysql --login-path=localhost -A -D $db -e \"source $outfile\"");
        my $impout = runlogcmd("$imp");
        if ( $impout->[2] ) {
            logMessage( 'error', "$impout->[1]" );
        } else {
            $row->delete;
        }
    }

}
