#!perl
use strict;
use warnings;
use DBIx::Fast;
use Test::More;
use Test::Exception;

plan( skip_all => 'Skip tests on Windows' ) if $^O eq 'MSWin32';

dies_ok { 1 / 0 } 'Ilegal division 1 / 0';

my $db = DBIx::Fast->new( SQLite => 't/db/test.db' , PrintError => 1 , RaiseError => 0);

dies_ok { $db->_dsn_to_dbi('SSS://sql:pass@host:/dbname') } '_dsn_to_dbi : Bad string';
dies_ok { $db->_dsn_to_dbi('sql://user@host/dbname') }      '_dsn_to_dbi : Bad DSN';

$db = DBIx::Fast->new( SQLite => 't/db/test.db' , PrintError => 1 , RaiseError => 0);

dies_ok { DBIx::Fast->new( driver => 'MrTester' ) } 'DBIx::Fast->new( driver => "MrTester" ) dies';

can_ok $db,'Exception';

throws_ok { $db->TableName('("4928') } qr/Exception: TableName not valid/, "Exception => TableName()";
throws_ok { $db->Exception('Tester') } qr/Exception: Tester/, "Exception('Tester')";

throws_ok { $db->_check_dsn('dbx:KikoTT:db:bd') } qr/Exception/, "_check_dsn Failed DBI";
# A dbi: DSN with no driver field is still rejected (the driver-specific
# remainder is otherwise left to DBI, so dbi:SQLite::memory: is now accepted).
throws_ok { $db->_check_dsn('dbi::nodriver') } qr/Exception/, "_check_dsn rejects a DSN with no driver";
# NOTE: no "missing host" assertion - dbi: DSNs never validated a host (SQLite
# DSNs legitimately have none); the old SIG{__DIE__} version of that test had
# been silently asserting nothing for years.

throws_ok { DBIx::Fast->new( Error => 1 ) } qr/Exception: Need a DSN or Host/, "Need a DSN or Host";

# --- 0.17: Exception message honors errors_redact ---------------------------
{
    my $rdb = DBIx::Fast->new( SQLite => 't/db/test.db',
                               RaiseError => 1, PrintError => 0,
                               errors_redact => 1 );
    eval { $rdb->Exception(q{bad value 'super-secret-token' rejected}) };
    unlike $@, qr/super-secret-token/, 'redacted Exception hides the literal';
    like   $@, qr/<redacted>/,         'redaction marker present';
}

# --- 0.17: last_error attached only when recent -----------------------------
{
    my $edb = DBIx::Fast->new( SQLite => 't/db/test.db',
                               RaiseError => 1, PrintError => 0 );

    $edb->set_error(42, 'fresh contextual error');
    eval { $edb->Exception('boom') };
    like $@, qr/Last error: .*fresh contextual error/,
        'recent last_error is attached';

    # Age the recorded error via the (mutable by reference) errors buffer.
    $edb->errors->[-1]{time} -= 3600;
    eval { $edb->Exception('boom again') };
    unlike $@, qr/Last error/,
        'stale last_error is not attached';
}

# --- 0.17: failed txn records the event once, not three times ---------------
{
    my $tdb = DBIx::Fast->new( SQLite => 't/db/test.db',
                               RaiseError => 1, PrintError => 0 );
    eval {
        $tdb->txn(sub {
            $tdb->exec('SELECT * FROM no_such_table_at_all');
        }, { max_retries => 0, retry_delay => 0 });
    };
    ok $@, 'transaction failed as expected';
    my @related = grep { $_->{error} =~ /no_such_table_at_all|Transaction failed/ }
                  @{ $tdb->errors };
    is scalar @related, 1,
        'DB-reported failure recorded once (no duplicate Transaction failed)';
}

done_testing();
