#!/usr/bin/env perl
use v5.36;
use strict;
use warnings;
use Benchmark qw(:all);
use Params::Filter qw/filter/;

say "=" x 80;
say "Params::Filter: Real-World Validation Performance";
say "=" x 80;
say "";
say "This benchmark demonstrates the ACTUAL value of Params::Filter:";
say "Reducing data BEFORE expensive validation operations.";
say "";

# ============================================================================
# REALISTIC VALIDATION FUNCTIONS
# ============================================================================

# Type checker (simulates Type::Tiny or similar)
sub validate_type {
    my ($value, $type) = @_;
    return 0 unless defined $value;

    if ($type eq 'email') {
        return $value =~ /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[A-Z]{2,}$/i ? 1 : 0;
    }
    elsif ($type eq 'phone') {
        return $value =~ /^\d{3}-\d{4}$/ ? 1 : 0;
    }
    elsif ($type eq 'zip') {
        return $value =~ /^\d{5}(-\d{4})?$/ ? 1 : 0;
    }
    elsif ($type eq 'integer') {
        return $value =~ /^\d+$/ ? 1 : 0;
    }
    return 1;
}

# Comprehensive validation pipeline
sub comprehensive_validation {
    my ($data, $fields_to_validate) = @_;

    my $valid = 1;

    # Validate each field according to its type
    for my $field (@$fields_to_validate) {
        next unless exists $data->{$field};

        my %field_types = (
            email => 'email',
            phone => 'phone',
            zip => 'zip',
            age => 'integer',
            name => 'string',
            city => 'string',
            username => 'string',
        );

        my $type = $field_types{$field} || 'string';
        $valid &&= validate_type($data->{$field}, $type);
    }

    # Simulate expensive database lookup (100 iterations)
    if ($valid) {
        my $sum = 0;
        $sum += $_ for 1..100;
    }

    return $valid;
}

# ============================================================================
# PRE-GENERATE ALL TEST DATA (avoid Benchmark scoping issues)
# ============================================================================

say "Generating test data...";
my @form_submissions;
my @all_field_lists;
my @filtered_field_lists;

for my $idx (1..1000) {
    my $form = {
        username => "user$idx",
        email => "user$idx\@example.com",
        name => "User Name $idx",
        age => int(rand(50)) + 18,
        city => "City $idx",
        phone => "555-$idx",
        zip => "12345",
        state => 'CA',
        address => "$idx Main St",
        address2 => "Apt $idx",
        country => 'USA',
        company => "Company $idx",
        title => "Job Title $idx",
        website => "http://example.com",
        bio => "Bio $idx",
        password => "secret$idx",
        password_confirm => "secret$idx",
        ssn => "123-45-6789",
        credit_card => "4111-1111-1111-1111",
        admin_token => "admin-token-$idx",
    };

    push @form_submissions, $form;
    push @all_field_lists, [keys %$form];
    push @filtered_field_lists, [qw/username email name age city phone zip state address/];
}

my $user_filter = Params::Filter->new_filter({
    required => [qw/username email name age city/],
    accepted => [qw/phone zip state address/],
    excluded => [qw/password password_confirm ssn credit_card admin_token/],
});

say "Data generated. Starting benchmarks...";
say "";

# ============================================================================
# BENCHMARK 1: Validate Everything (Naive Approach)
# ============================================================================
say "-" x 80;
say "Benchmark 1: Naive Approach - Validate ALL 20 Fields";
say "-" x 80;
say "Processing 1,000 form submissions with 20 fields each";
say "";

cmpthese(-3, {
    validate_all_naive => sub {
        for my $idx (0..$#form_submissions) {
            my $form = $form_submissions[$idx];
            my $fields = $all_field_lists[$idx];
            my $valid = comprehensive_validation($form, $fields);
        }
    },
});

say "";
say "Result: 20,000 total field validations (20 fields × 1,000 forms)";
say "";

# ============================================================================
# BENCHMARK 2: Filter First, Then Validate
# ============================================================================
say "-" x 80;
say "Benchmark 2: Smart Approach - Filter First, Then Validate";
say "-" x 80;
say "Processing 1,000 form submissions, filter to 8 core fields first";
say "";

cmpthese(-3, {
    filter_then_validate => sub {
        for my $idx (0..$#form_submissions) {
            my $form = $form_submissions[$idx];
            my ($filtered, $msg) = $user_filter->apply($form);

            if ($filtered) {
                my $valid = comprehensive_validation($filtered, $filtered_field_lists[$idx]);
            }
        }
    },
});

say "";
say "Result: 8,000 total field validations (8 fields × 1,000 forms)";
say "Reduction: 12,000 fewer validations (60% reduction)";
say "";

# ============================================================================
# BENCHMARK 3: Direct Comparison
# ============================================================================
say "-" x 80;
say "Benchmark 3: Side-by-Side Comparison";
say "-" x 80;

cmpthese(-3, {
    naive_validate_all => sub {
        for my $idx (0..$#form_submissions) {
            my $form = $form_submissions[$idx];
            my $fields = $all_field_lists[$idx];
            my $valid = comprehensive_validation($form, $fields);
        }
    },
    smart_filter_first => sub {
        for my $idx (0..$#form_submissions) {
            my $form = $form_submissions[$idx];
            my ($filtered, $msg) = $user_filter->apply($form);

            if ($filtered) {
                my $valid = comprehensive_validation($filtered, $filtered_field_lists[$idx]);
            }
        }
    },
});

say "";
say "=" x 80;
say "INTERPRETATION";
say "=" x 80;
say "";
say "This benchmark shows the REAL value of Params::Filter:";
say "";
say "1. Naive approach validates ALL 20 fields (including sensitive data)";
say "2. Smart approach filters to 8 fields BEFORE validation";
say "3. Fewer validations = faster processing + better security";
say "";
say "Key insight: Params::Filter isn't about being faster than manual operations.";
say "It's about reducing your data BEFORE expensive downstream processing.";
say "";
say "In this example:";
say "  - 60% fewer validations (20 → 8 fields)";
say "  - Sensitive fields (password, SSN, credit card) never reach validation";
say "  - Compliance and security improved by design";
say "";
say "The overhead of Params::Filter is SMALL compared to validation savings.";
say "";
say "=" x 80;
