use strict;
use warnings;
no warnings 'once';
use Test::More;

require './tests/MySQLTuner/TestHelper.pm';

# Mocking variables and functions from mysqltuner.pl
our %opt = (
    "ignore-tables" => ''
);
our %myvar;
our %mystat;
our %mycalc;
our @adjvars;
our @generalrec;
our %result;

sub subheaderprint { }
sub infoprint { }
sub badprint { }
sub goodprint { }
sub debugprint { }
sub hr_bytes { return $_[0]; }
sub hr_num { return $_[0]; }
sub percentage { return "10"; }

# Mocking select_array and select_one for collation checks
our @mock_dblist = ('db1');
our %mock_queries = (
    "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN ( 'mysql', 'performance_schema', 'information_schema', 'sys' );" => ['db1'],
    "SELECT SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH), SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(TABLE_NAME), COUNT(DISTINCT(TABLE_COLLATION)), COUNT(DISTINCT(ENGINE)) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('mysql', 'performance_schema', 'information_schema', 'sys');" => "100 1024 1024 2048 2 2 1",
    "SELECT TABLE_SCHEMA, SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH), SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(DISTINCT ENGINE), COUNT(TABLE_NAME), COUNT(DISTINCT(TABLE_COLLATION)), COUNT(DISTINCT(ENGINE)) FROM information_schema.TABLES WHERE TABLE_SCHEMA='db1' GROUP BY TABLE_SCHEMA ORDER BY TABLE_SCHEMA" => "db1 100 1024 1024 2048 1 2 2 1",
);

sub mysql_version_ge { return 1; }

sub select_one {
    my $query = shift;
    return $mock_queries{$query} if exists $mock_queries{$query};
    if ($query =~ /BASE TABLE/ && $query =~ /db1/) { return 2; }
    if ($query =~ /VIEW/ && $query =~ /db1/) { return 0; }
    if ($query =~ /STATISTICS/ && $query =~ /db1/) { return 2; }
    return "NULL";
}

sub select_array {
    my $query = shift;
    if ($query eq "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN ( 'mysql', 'performance_schema', 'information_schema', 'sys' );") {
        return @mock_dblist;
    }
    if ($query =~ /CHARACTER_SET_NAME/) { return ('utf8mb4'); }
    if ($query =~ /TABLE_COLLATION/ && $query =~ /db1/) {
        # This is where we simulate mismatch
        if ($opt{"ignore-tables"} =~ /mismatch_table/) {
            return ('utf8mb4_general_ci');
        }
        return ('utf8mb4_general_ci', 'latin1_swedish_ci');
    }
    if ($query =~ /DISTINCT\(ENGINE\)/) { return ('InnoDB'); }
    return ();
}

# The logic to be tested (simplified/extracted from mysql_databases)
sub test_collation_logic {
    my @dblist = ('db1');
    @generalrec = ();
    foreach my $db (@dblist) {
        # Simulation of mysql_databases logic for collation mismatch check
        my @dbinfo = split /\s/, select_one("SELECT TABLE_SCHEMA, SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH), SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(DISTINCT ENGINE), COUNT(TABLE_NAME), COUNT(DISTINCT(TABLE_COLLATION)), COUNT(DISTINCT(ENGINE)) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$db' GROUP BY TABLE_SCHEMA ORDER BY TABLE_SCHEMA");
        
        my $coll_count = $dbinfo[7];
        
        # If ignore-tables is active, we need to manually adjust $coll_count in our mock or the real function needs to use filtered queries
        # For this test, we assume the REAL implementation will filter via SQL or post-processing.
        # Let's mock a post-processing filtering behavior if we implemented it as such.
        
        if ($opt{"ignore-tables"}) {
            # Simulate SQL that filters ignored tables
            if ($opt{"ignore-tables"} =~ /mismatch_table/) {
                $coll_count = 1; # Filtered
            }
        }

        if ( $coll_count > 1 ) {
            push( @generalrec, "Check all table collations are identical for all tables in $db database." );
        }
    }
}

# Test 1: Mismatch detected without ignore-tables
$opt{"ignore-tables"} = '';
test_collation_logic();
ok(grep(/Check all table collations are identical/, @generalrec), "Should warn about collation mismatch by default");

# Test 2: Mismatch suppressed with ignore-tables
$opt{"ignore-tables"} = 'mismatch_table';
test_collation_logic();
ok(!grep(/Check all table collations are identical/, @generalrec), "Should NOT warn about collation mismatch when table is ignored");

done_testing();
