use strict;
use warnings;
use Test::More;
use Test::Exception;
use DBIx::Fast;

eval "use DBD::SQLite 1.74";
plan skip_all => "DBD::SQLite 1.74 required" if $@;

use DBIx::Fast::Profile::Base;
use DBIx::Fast::Profile::SQLite;

my $db = DBIx::Fast->new(
    dsn        => 'dbi:SQLite:dbname=:memory:',
    driver     => 'SQLite',
    RaiseError => 1,
    PrintError => 0,
);

# --- Profile::Base ---

subtest 'Profile::Base - constructor' => sub {
    my $base = DBIx::Fast::Profile::Base->new(dbix => $db);
    ok($base, 'Base profile created');
    is($base->dbix, $db, 'dbix accessor works');
};

subtest 'Profile::Base - missing dbix croak' => sub {
    throws_ok { DBIx::Fast::Profile::Base->new(dbix => undef) }
        qr/Missing required parameter 'dbix'/,
        'Missing dbix throws';
};

subtest 'Profile::Base - enabled accessor' => sub {
    my $base = DBIx::Fast::Profile::Base->new(dbix => $db);
    is($base->enabled, 1, 'Enabled by default');

    $base->enabled(0);
    is($base->enabled, 0, 'Disabled');

    $base->enabled(1);
    is($base->enabled, 1, 'Re-enabled');
};

subtest 'Profile::Base - slow_query accessor' => sub {
    my $base = DBIx::Fast::Profile::Base->new(dbix => $db, slow_query => 2.5);
    is($base->slow_query, 2.5, 'Custom slow_query');

    $base->slow_query(0.5);
    is($base->slow_query, 0.5, 'slow_query setter works');
};

subtest 'Profile::Base - add_query is no-op' => sub {
    my $base = DBIx::Fast::Profile::Base->new(dbix => $db);
    lives_ok { $base->add_query() } 'add_query is a no-op';
    lives_ok { $base->add_query('SELECT 1', [], 0, 1) } 'add_query with args is no-op';
};

subtest 'Profile::Base - abstract methods croak' => sub {
    my $base = DBIx::Fast::Profile::Base->new(dbix => $db);

    throws_ok { $base->init }
        qr/Not implemented/, 'init croaks';
    throws_ok { $base->get_slow_queries }
        qr/Not implemented/, 'get_slow_queries croaks';
    throws_ok { $base->get_stats }
        qr/Not implemented/, 'get_stats croaks';
    throws_ok { $base->print_stats }
        qr/Not implemented/, 'print_stats croaks';
};

# --- Profile::SQLite ---

subtest 'Profile::SQLite - constructor' => sub {
    my $sqlite = DBIx::Fast::Profile::SQLite->new(dbix => $db);
    ok($sqlite, 'SQLite profile created');
    isa_ok($sqlite, 'DBIx::Fast::Profile::SQLite');
    isa_ok($sqlite, 'DBIx::Fast::Profile::Base');
};

subtest 'Profile::SQLite - all no-op methods' => sub {
    my $sqlite = DBIx::Fast::Profile::SQLite->new(dbix => $db);

    # Method => args. Args mirror the MariaDB profile signatures so we
    # also verify SQLite accepts the same calls polymorphically.
    my @cases = (
        [ init                      => [] ],
        [ get_slow_queries          => [] ],
        [ get_query_profile         => [42] ],
        [ get_stats                 => [] ],
        [ print_stats               => [] ],
        [ explain_query             => ['SELECT 1', 'p1'] ],
        [ get_table_stats           => ['t'] ],
        [ get_index_stats           => ['t'] ],
        [ analyze_indexes           => ['t'] ],
        [ print_index_analysis      => ['t'] ],
        [ get_index_metrics         => ['t'] ],
        [ monitor_connections       => [] ],
        [ get_current_connections   => [] ],
        [ get_processes             => [] ],
        [ print_connection_monitor  => [] ],
        [ start_connection_monitor  => [1, 1] ],
    );

    for my $case (@cases) {
        my ($method, $args) = @$case;
        lives_ok { $sqlite->$method(@$args) } "$method is no-op";
    }
};

subtest 'Profile::SQLite - enabled/slow_query inherited' => sub {
    my $sqlite = DBIx::Fast::Profile::SQLite->new(
        dbix => $db, enabled => 0, slow_query => 3.0
    );
    is($sqlite->enabled, 0, 'Inherited enabled');
    is($sqlite->slow_query, 3.0, 'Inherited slow_query');
};

# --- Integration: profiler() from Fast.pm ---

subtest 'Fast profiler() returns SQLite profile' => sub {
    my $profiler = $db->profiler;
    isa_ok($profiler, 'DBIx::Fast::Profile::SQLite');

    # Cached
    my $profiler2 = $db->profiler;
    is($profiler, $profiler2, 'Profiler cached on second call');
};

done_testing;
