#!/usr/bin/perl
# template v1.0  (c) 27.11.2015 by Andreas Ley  (u) 6.4.2024
# 

use locale;
use Getopt::Std;
#use File::Spec::Functions;
use Data::Dumper;
#warn Data::Dumper->Dump([\%hash],['*hash']) if ($opt_D>0);

sub usage
{
	my $image = $0;
	$image =~ s!.*/!!;
	print STDERR "Usage: $image src dst key=value|key==value,value[,...]  [...]]\n";
	exit(1);
}

getopts('DL:hxv') or &usage;

&usage if (defined($opt_h) || scalar(@ARGV)<3);

$opt_D = $opt_L if (defined($opt_L));
if (defined($opt_v) || defined($opt_D)) {
	$|=1;
	select((select(STDERR),$|=1)[0]);
}

$src = shift;
$dst = shift;

for (@ARGV) {
	if (/==/) {
		#warn "$` => $'\n";
		$substitutions{$`} = [split(',',$')];
	}
	elsif (/=/) {
		#warn "$` => $'\n";
		$substitutions{$`} = $';
	}
	Data::Dumper->Dump([\%substitutions],['*']) if (defined($opt_D));
}

&template_file($src,$dst,\%substitutions);

################################################################################
#
# Copy a template to an instance, substituting given tokens
#
sub read_file
{
	my ($file) = @_;
	print STDERR "Reading $file\n" if ($opt_D);

	my ($content);
	open(FILE,$file) || die "Can't read $file: $!\n";
	while (<FILE>) {
		$content .= $_;
	}
	close(FILE);
	return($content);
}

sub template
{
	my ($template,$substitutions) = @_;

	my $content;
	for (split(/^/m,$template)) {
		if (/^%!([^%]+)%/) {
			next if ($substitutions->{$1});
			$_ = $';
		}
		elsif (/^%([^%]+)%/) {
			next unless ($substitutions->{$1});
			$_ = $';
		}
		# FIXME: should this be .../g ?!
		while (/@([^[@][^@]*)@/) {
			$_ = $`.$substitutions->{$1}.$';
		}
		# Do not use multiple @[VARIABLE]@ within one line!
		# This will replace the first instance, but would not
		# re-line-parse the multi-line result!
		while (/@\[([^@\]]+)\]@/) {
			$_ = join('',map($`.$_.$',@{$substitutions->{$1}}));
		}
		$content .= $_;
	}
	return($content);
}

sub write_file
{
	my ($content,$dst) = @_;
	print STDERR "Writing $dst\n" if ($opt_D);

	open(DST,'>',$dst) || die "Can't write to $dst: $!\n";
	# FIXME: die with a better error message
	print DST $content or die;
	close(DST) or die;
}

sub template_file
{
	my ($src,$dst,$substitutions) = @_;
	print STDERR "Creating $dst from $src\n" if ($opt_D);

	&write_file(&template(&read_file($src),$substitutions),$dst);
}
