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

# rank 14: PostgreSQL last_id. Gated on a live PostgreSQL (e.g. a docker
# container): DBIX_FAST_TEST_PG='postgres://user:pass@127.0.0.1:5432/dbix_test'.

my $dsn = $ENV{DBIX_FAST_TEST_PG}
  or plan skip_all => 'DBIX_FAST_TEST_PG env var not set '
                    . '(e.g. postgres://user:pass@127.0.0.1:5432/dbix_test)';

eval { require DBD::Pg; 1 }    or plan skip_all => 'DBD::Pg required';
eval { require DBIx::Fast; 1 } or plan skip_all => 'DBIx::Fast required';
DBIx::Fast->import;

my $db = eval {
    DBIx::Fast->new(dsn => $dsn, RaiseError => 1, PrintError => 0);
};
plan skip_all => "Cannot connect to PostgreSQL ($dsn): $@" if $@ or !$db;

# Suppress NOTICE chatter (e.g. "table ... does not exist, skipping" from
# DROP TABLE IF EXISTS) so the test output stays clean.
$db->exec(q{SET client_min_messages TO WARNING});

is($db->dbd, 'Pg', 'driver resolved to Pg');

$db->exec('DROP TABLE IF EXISTS pglid_items');
$db->exec(q{
    CREATE TABLE pglid_items (
        id   SERIAL PRIMARY KEY,
        name TEXT NOT NULL
    )
});

subtest 'insert sets last_id from the serial PK' => sub {
    my $id1 = $db->insert('pglid_items', { name => 'first' });
    ok($id1, 'last_id returned from insert');
    is($db->last_id, $id1, 'last_id accessor matches');

    my $id2 = $db->insert('pglid_items', { name => 'second' });
    ok($id2 > $id1, 'last_id advances on the next insert');

    is($db->val('SELECT name FROM pglid_items WHERE id = ?', $id1), 'first',
       'row is reachable by the returned id');
};

subtest 'upsert ON CONFLICT (excluded) works on Pg' => sub {
    $db->exec('DROP TABLE IF EXISTS pglid_prices');
    $db->exec(q{
        CREATE TABLE pglid_prices (sku TEXT PRIMARY KEY, price NUMERIC)
    });
    $db->upsert('pglid_prices', { sku => 'A', price => 1 }, ['sku']);
    $db->upsert('pglid_prices', { sku => 'A', price => 2 }, ['sku']);
    like($db->last_sql, qr/ON CONFLICT/, 'emits ON CONFLICT for Pg');
    is($db->val('SELECT price FROM pglid_prices WHERE sku = ?', 'A'), 2,
       'conflict updated the price');
};

# --- Cleanup ---
$db->exec("DROP TABLE IF EXISTS $_") for qw(pglid_items pglid_prices);

done_testing;
