package Common::DB::Diff::Rowset;

use strict;
use warnings;

use JSON::XS;
use List::Util qw(min max);
use Digest::MD5 qw(md5 md5_hex md5_base64);

use base 'Class::Accessor';

__PACKAGE__->mk_accessors(qw/count minkey maxkey rowkeys md5rows md5keys rows sql/);

use lib '/app/tools/common/lib';
use Common::MD5Sum;

sub new {
    my $class = shift;
    my $rows  = shift;
    my $self  = {};
    bless $self, $class;
    $self->_init($rows);
    $self;
}

sub _init {
    my $self = shift;
    my $rows = shift;

    my $rowkeys = [ sort keys %{$rows} ];

    if ( keys %{$rows} ) {
        if ( $rowkeys->[0] !~ m/.*-.*/ ) {
            $self->minkey( min( @{$rowkeys} ) );
            $self->maxkey( max( @{$rowkeys} ) );
        }
    }
    $self->count( scalar @{$rowkeys} );

    $self->md5rows( Common::MD5Sum::refsum($rows) );
    $self->md5keys( Common::MD5Sum::refsum($rowkeys) );

    $self->rowkeys($rowkeys);
    $self->rows($rows);

}

sub compare {
    my $self = shift;
    my $rset = shift;

    ## suppress cols that match
    my $suppress = shift;

    my $mismatches;
    foreach my $key ( @{ $self->rowkeys } ) {
        my $tuple1 = $self->rows->{$key};
        my $tuple2 = $rset->rows->{$key};

        my $md5sum1 = Common::MD5Sum::refsum($tuple1);
        my $md5sum2 = Common::MD5Sum::refsum($tuple2);

        next if $md5sum1 eq $md5sum2;

        foreach my $col ( keys %{$tuple1} ) {
            my $val1 = defined $tuple1->{$col} ? $tuple1->{$col} : 'NULL';
            my $val2 = defined $tuple2->{$col} ? $tuple2->{$col} : 'NULL';

            my $match = $val1 eq $val2 ? 1 : 0;
            my $href  = { 'primary' => $val1, 'replica' => $val2, 'match' => $match };

            ## include matches if not suppressed or not matched
            $mismatches->{$key}->{$col} = $href if not $match or ( $match and not $suppress );
        }

    }
    $mismatches;

}

1;

