#! /usr/bin/env perl

use strict;
use warnings;
use File::Basename;
use File::Find;

my $searchdir = shift;
my $outfile = shift;

if (not defined $outfile)
  {
    print "Usage: $0 search-dir outfile\n";
    print "\n";
    print "Example: $0 /path/to/obj-dir /path/to/your/l4re/src/dir/compile_commands.json\n";
    exit 1;
  }

open(my $out, ">$outfile") or die "Cannot open '$outfile': $!";

my @db;

sub add_cmd
{
  return unless /\.cmd$/;

  open(my $fh_cmd, $_) or die "Cannot open '$File::Find::name': $!";
  my $cmd;
  my $source;
  my $obj;
  while (<$fh_cmd>)
    {
      chomp;
      $cmd    = $1 if /^savedcmd_\S+\s+:=\s+(.+)/;
      $source = $1 if /^source_\S+\s+:=\s+(.+)/;
      $obj    = $1 if /^savedcmd_(\S+)\s+:=\s+.+/;
    }

  return unless defined $cmd and defined $source and defined $obj;

  my $obj_dir = dirname($obj);
  my $obj_path = $File::Find::dir =~ s|\Q/$obj_dir\E$||r;

  sub json_escape { return shift =~ s/(["\\])/\\$1/gr; }

  push @db, {
    "file"      => json_escape($source),
    "directory" => json_escape($obj_path),
    "command"   => json_escape($cmd),
    "output"    => json_escape("$obj_path/$obj"),
  }
}

find(\&add_cmd, $searchdir);

my @sorted = sort { $b->{file} cmp $a->{file} } @db;

print $out "[\n";
my $comma = "";
for my $entry (@sorted)
  {
    print $out $comma;
    print $out "  {\n";
    print $out "    \"file\": \"$entry->{file}\",\n";
    print $out "    \"directory\": \"$entry->{directory}\",\n";
    print $out "    \"command\": \"$entry->{command}\",\n";
    print $out "    \"output\": \"$entry->{output}\"\n";
    print $out "  }";
    $comma = ",\n";
  }
print $out "\n]\n";
