# Batched version of util/dofile.pl for Bazel.
#
# Processes multiple OpenSSL .in templates in a single Perl invocation,
# writing each result directly to its output file.  This avoids the
# per-template process-creation overhead that dominates on Windows.
#
# Usage: batch_dofile.pl --in=<template> --out=<output> [--in=... --out=...] ...
#
# Must be invoked with -Mconfigdata (and any other -M flags the
# templates need, e.g. -Moids_to_c).

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/perl";
use OpenSSL::fallback "$FindBin::Bin/../external/perl/MODULES.txt";
use OpenSSL::Template;

die "You must run this script with -Mconfigdata\n"
    if !exists($config{target});

my @pairs;
my $i = 0;
while ($i < scalar(@ARGV)) {
    my $arg = $ARGV[$i];
    if ($arg =~ /^--in=(.+)$/) {
        my $in = $1;
        $i++;
        die "Expected --out=<path> after --in=$in\n"
            if $i >= scalar(@ARGV) || $ARGV[$i] !~ /^--out=(.+)$/;
        push @pairs, { in => $in, out => $1 };
    } else {
        die "Unexpected argument: $arg\n";
    }
    $i++;
}

die "No --in/--out pairs given\n" unless @pairs;

my @autowarntext = (
    "WARNING: do not edit!",
    "Generated by batch_dofile.pl"
);

my $failed = 0;
sub errorcallback {
    my %args = @_;
    print STDERR $args{error};
    $failed++;
    return undef;
}

my $prepend = <<"_____";
use File::Spec::Functions;
use lib '$FindBin::Bin/../Configurations';
use lib '$config{builddir}';
use platform;
_____

for my $pair (@pairs) {
    my $template = OpenSSL::Template->new(
        TYPE     => 'FILE',
        SOURCE   => $pair->{in},
        FILENAME => $pair->{in},
    );
    die "Couldn't create template for $pair->{in}: $Text::Template::ERROR\n"
        if !defined($template);

    my $result = $template->fill_in(
        TYPE     => 'FILE',
        SOURCE   => $pair->{in},
        FILENAME => $pair->{in},
        HASH     => {
            config       => \%config,
            target       => \%target,
            disabled     => \%disabled,
            withargs     => \%withargs,
            unified_info => \%unified_info,
            autowarntext => \@autowarntext,
        },
        BROKEN  => \&errorcallback,
        PREPEND => $prepend,
        PACKAGE => 'OpenSSL::safe',
    );
    exit 1 if $failed;

    open(my $fh, '>', $pair->{out})
        or die "Can't open $pair->{out}: $!\n";
    print $fh $result;
    close $fh;
}
