#!/usr/bin/env perl
# t/04-cli.t - Tests for the xsone command-line tool

use strict;
use warnings;
use Test::More;
use File::Spec;
use File::Path qw(make_path remove_tree);
use FindBin qw($Bin);

my $bin = File::Spec->catfile($Bin, '..', 'bin', 'xsone');
my $src_dir = File::Spec->catdir($Bin, 'lib', 'TestModule', 'xs');

# Create a temporary directory for test files under t/
my $tmpdir = File::Spec->catdir($Bin, 'tmp', '04-cli');
remove_tree($tmpdir) if -d $tmpdir;
make_path($tmpdir);
END { remove_tree($tmpdir) if $tmpdir && -d $tmpdir }

# Skip if bin/xsone doesn't exist
plan skip_all => "bin/xsone not found" unless -f $bin;

# =============================================================================
# Test basic CLI usage
# =============================================================================

subtest 'Basic CLI usage' => sub {
    plan tests => 4;

    my $output = File::Spec->catfile($tmpdir, 'cli-basic.xs');

    my $result = `$^X $bin --src "$src_dir" --out "$output" 2>&1`;
    is($?, 0, 'CLI exits successfully');
    like($result, qr/Combined 4 files/, 'Reports file count');
    ok(-f $output, 'Output file created');

    my $content = read_file($output);
    like($content, qr/AUTO-GENERATED BY ExtUtils::XSOne/, 'Has generated header');
};

# =============================================================================
# Test verbose mode
# =============================================================================

subtest 'Verbose mode' => sub {
    plan tests => 3;

    my $output = File::Spec->catfile($tmpdir, 'cli-verbose.xs');

    my $result = `$^X $bin --verbose --src "$src_dir" --out "$output" 2>&1`;
    is($?, 0, 'CLI exits successfully');
    like($result, qr/Processing files in order/, 'Verbose shows processing');
    like($result, qr/_header\.xs.*context\.xs.*utils\.xs.*_footer\.xs/s, 'Lists files');
};

# =============================================================================
# Test short options
# =============================================================================

subtest 'Short options' => sub {
    plan tests => 2;

    my $output = File::Spec->catfile($tmpdir, 'cli-short.xs');

    my $result = `$^X $bin -s "$src_dir" -o "$output" -v 2>&1`;
    is($?, 0, 'Short options work');
    ok(-f $output, 'Output created with short options');
};

# =============================================================================
# Test custom order
# =============================================================================

subtest 'Custom order via CLI' => sub {
    plan tests => 2;

    my $output = File::Spec->catfile($tmpdir, 'cli-order.xs');

    my $result = `$^X $bin --src "$src_dir" --out "$output" --order _header --order utils --order context --order _footer 2>&1`;
    is($?, 0, 'CLI with --order exits successfully');

    my $content = read_file($output);
    like($content, qr/Generated from:.*_header\.xs.*utils\.xs.*context\.xs.*_footer\.xs/s,
         'Custom order applied');
};

# =============================================================================
# Test error handling
# =============================================================================

subtest 'CLI error handling' => sub {
    plan tests => 3;

    # Missing --src
    my $result = `$^X $bin --out /tmp/out.xs 2>&1`;
    isnt($?, 0, 'Fails without --src');

    # Missing --out
    $result = `$^X $bin --src "$src_dir" 2>&1`;
    isnt($?, 0, 'Fails without --out');

    # Nonexistent source
    $result = `$^X $bin --src /nonexistent/path --out /tmp/out.xs 2>&1`;
    isnt($?, 0, 'Fails with nonexistent src');
};

# =============================================================================
# Test help
# =============================================================================

subtest 'Help option' => sub {
    plan tests => 2;

    my $result = `$^X $bin --help 2>&1`;
    # pod2usage exits with 1 for --help by default, which is normal behavior
    ok($? == 0 || ($? >> 8) == 1, '--help exits (0 or 1 is acceptable)');
    like($result, qr/--src.*--out/s, 'Help shows options');
};

# =============================================================================
# Helper
# =============================================================================

sub read_file {
    my ($path) = @_;
    open(my $fh, '<', $path) or die "Cannot read $path: $!";
    local $/;
    my $content = <$fh>;
    close($fh);
    return $content;
}

done_testing();
