#!/usr/bin/perl
use v5.36;
use File::Find;
use Path::Tiny;
my %already_included;
my $amalgam_h = "./checkit_tiff.amalgam.h";
my $amalgam_c = "./checkit_tiff.amalgam.c";
my $srcbase = "../src/";
my $program = "${srcbase}checkit_tiff.c";
my @includes = qw(headers lib/include lib/validate_icc/);
my $lines = 0;

sub amalgize_headers($srcfile, $tgtfile) {
    if (!exists $already_included{$srcfile}) {
        say "processing $srcfile";
        my @src = path($srcfile)->lines();
        foreach my $line (@src) {
            if ($line =~ m/^#include "([^"]*\.h)"/) {
                foreach my $include (@includes) {
                    my $include_file = path($srcbase)->child($include)->child($1);
                    if ($include_file->is_file) {
                        path($tgtfile)->append("/* --- BEGIN INCLUDED $include_file */\n");
                        amalgize_headers($include_file->stringify(), $tgtfile);
                        path($tgtfile)->append("/* --- END INCLUDED $include_file */\n\n");
                        last;
                    }
                }
            } elsif ($line =~ m/^#line/) {
                # ignore
            } else {
                if ($srcfile =~ m/\.h$/) {
                    path($tgtfile)->append($line);
                    $lines++;
                }
            }
        }
        $already_included{$srcfile}=1 unless $srcfile=~m/template/;
    } else {
        say "... ignoring $srcfile, because already included"
    }
    return 1;
}

sub amalgize_prog($srcfile, $tgtfile) {
    say "processing $srcfile";
    my @src = path($srcfile)->lines();
    foreach my $line (@src) {
        # #include "config_dsl.grammar.c"   /* yyparse() */
        if ($line =~ m/^#include "([^"]*\.c)"/) {
            my $include_file = path($srcfile)->parent()->child($1);
            if ($include_file->is_file) {
                path($tgtfile)->append("/* --- BEGIN INCLUDED $include_file */\n");
                path($tgtfile)->append($include_file->slurp);
                path($tgtfile)->append("/* --- END INCLUDED $include_file */\n\n");
            }
        } elsif ($line =~ m/^#include "([^"]*\.h)"/) {
           # ignore
        } elsif ($line =~ m/^#line/) {
           # ignore
        } else {
            path($tgtfile)->append($line);
            $lines++;
        }
    }
    return 1;
}

# main
path($amalgam_h)->remove;
path($amalgam_c)->remove;
my @lib;
sub wanted {
    my ($dev,$ino,$mode,$nlink,$uid,$gid);
    (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
    -f _ &&
    /^.*\.c\z/s
    && push(@lib, $File::Find::name);
}
File::Find::find({wanted => \&wanted}, "${srcbase}lib/", "${srcbase}parser/" );
say "-- parsing headers for lib";
foreach my $lib (@lib) {
    amalgize_headers($lib, $amalgam_h);
}
say "-- parsing headers for prog";
amalgize_headers($program, $amalgam_h);
path($amalgam_c)->append("#include \"$amalgam_h\"\n");
say "-- parsing source for lib";
foreach my $lib (@lib) {
    next if ($lib =~ m/config_dsl.grammar.c/);
    amalgize_prog($lib, $amalgam_c);
}
say "-- parsing source for prog";
amalgize_prog($program, $amalgam_c);
say "-- finished";
say "$lines lines processed";
say  <<"COMPILE";
compile it with:
  gcc -DHAVE_MMAP -DPCRE2_STATIC -DREPO_REVISION=\\"998\\" -DUSE_LIBPCRE2 -DVERSION=\\"amalgamized\\" -D_GNU_SOURCE \\
   -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -std=gnu11 -L/usr/lib/x86_64-linux-gnu checkit_tiff.amalgam.c \\
   -lpcre2-8
COMPILE


