use strict;
use warnings;
use Test::More;
use Path::Tiny;
use lib "t/lib";

# Disable XS
use Protobuf;
$Protobuf::HAS_XS = 0;

# Log::Any::Adapter->set('Stderr'); # Uncomment for debugging

use Protobuf::DescriptorPool;

subtest 'Full Pure-Perl Lifecycle' => sub {
    my $pool = Protobuf::DescriptorPool->new();
    my $bin_data = path('t/data/test_descriptor.bin')->slurp_raw;

    # Loading the descriptor set triggers ClassGenerator
    $pool->add_serialized_file_descriptor_set($bin_data);

    # Check if classes were generated
    ok(Protobuf_perl_test::Test::TestMessage->can('new'), 'Generated TestMessage class');

    my $msg = Protobuf_perl_test::Test::TestMessage->new();
    is(ref($msg->{_engine}), 'Protobuf::Engine::PurePerl', 'Using PP engine by default when XS is off');

    # Test Perl-level accessors generated by ClassGenerator
    $msg->value(123);
    $msg->test_string('pure perl');

    is($msg->value, 123, 'Getter works');
    ok($msg->has_value, 'has_ works');

    my $bin = $msg->serialize();
    ok(length($bin) > 0, 'Serialized');

    my $decoded = Protobuf_perl_test::Test::TestMessage->parse($bin);
    ok($decoded, 'Parsed successfully');
    is(ref($decoded->{_engine}), 'Protobuf::Engine::PurePerl', 'Decoded message also uses PP engine');

    is($decoded->value, 123, 'Parsed value matches');
    is($decoded->test_string, 'pure perl', 'Parsed string matches');

    $decoded->clear_value();
    ok(!$decoded->has_value, 'clear_ works');
};

subtest 'Pure-Perl Nested Messages Lifecycle' => sub {
    my $msg = Protobuf_perl_test::Test::TestMessage->new();
    $msg->test_string('pure perl');
    my $nested = Protobuf_perl_test::Test::NestedMessage->new();
    $nested->nested_string('deep');

    $msg->nested_message($nested);

    my $bin = $msg->serialize();
    my $decoded = Protobuf_perl_test::Test::TestMessage->parse($bin);

    my $d_nested = $decoded->nested_message;
    ok($d_nested, 'Got nested message');
    is($d_nested->nested_string, 'deep', 'Nested value matches');

    # Test to_perl
    my $hash = $decoded->to_perl();
    is(ref($hash), 'HASH', 'to_perl returns HashRef');
    is($hash->{test_string}, 'pure perl', 'Top-level string in hash');
    is($hash->{nested_message}{nested_string}, 'deep', 'Nested string in hash');
};

done_testing();
