#!/usr/bin/env raku

sub MAIN($release, Bool :$update-changelog = True, Bool :$update-version = True, Bool :$check-git-status = True) {
    if $check-git-status {
        unless run(<git diff --no-ext-diff --quiet>) and run(<git diff --no-ext-diff --cached --quiet>) {
            say "git status is not clean";
            exit 1;
        }
    }

    my $changelog-file = "docs/ChangeLog".IO;
    my $changelog = $changelog-file.open(:r);
    my @changelog-lines = $changelog.lines;
    my $old-version = 'VERSION'.IO.slurp.chomp;

    if $update-changelog {
        my @lines = get-commits($old-version, :subject);

        $changelog = $changelog-file.open(:w);
        $changelog.put: "New in $release\n";
        $changelog.put: "+ $_" for @lines;
        $changelog.put: '';
        $changelog.put: @changelog-lines.join: "\n";
    }
    else {
        for get-commits($old-version) -> $commit {
            my @files = run(<<git diff --name-only "$commit" "$commit^">>, :out).out.lines;
            for @files -> $file {
                next if $file eq 'VERSION'|'docs/ChangeLog';
                say "Commit {run(<<git show -s --oneline $commit>>, :out).out.slurp.chomp} not logged"
                    unless any(@changelog-lines) ~~ /$commit/;
            }
        }
    }

    if $update-version {
        "VERSION".IO.spurt: $release;
        run <git add VERSION>;
        run <git commit -v>;
        run 'make', 'release', "VERSION=$release";
    }

    my $builddir = $*TMPDIR.child("moarvm-release-test-{(^2**128).pick.base(36)}");
    say "Building in $builddir";
    $builddir.IO.mkdir;
    "$builddir/install".IO.mkdir;
    run <<perl Configure.pl "--prefix=$builddir/install">>;
    run <<make "-j$*KERNEL.cpu-cores()" install>>;

    %*ENV<TEST_JOBS> = $*KERNEL.cpu-cores;
    indir $builddir, {
        run <git clone https://github.com/perl6/nqp.git>;
        indir "nqp".IO, {
            run <<perl Configure.pl --backends=moar "--with-moar=$builddir/install/bin/moar" "--prefix=$builddir/install">>;
            run <make test>;
            run <make install>;
        };
        run <git clone https://github.com/rakudo/rakudo.git>;
        indir "rakudo".IO, {
            run <<perl Configure.pl "--with-nqp=$builddir/install/bin/nqp" "--prefix=$builddir/install">>;
            run <make test>;
            run <make spectest>;
            run <make stresstest>;
        }
    };

    my $debug-nfg-patch = q:to/PATCH/;
        diff --git a/src/strings/ops.h b/src/strings/ops.h
        index 5cdb3d355..fd20f1d50 100644
        --- a/src/strings/ops.h
        +++ b/src/strings/ops.h
        @@ -142 +142 @@ char * MVM_string_encoding_cname(MVMThreadContext *tc, MVMint64 encoding);
        -#define MVM_DEBUG_NFG 0
        +#define MVM_DEBUG_NFG 1
        @@ -145 +145 @@ char * MVM_string_encoding_cname(MVMThreadContext *tc, MVMint64 encoding);
        -#define MVM_DEBUG_NFG_STRICT 0
        +#define MVM_DEBUG_NFG_STRICT 1
        PATCH
    run(<patch -p1>, :in).in.spurt: $debug-nfg-patch, :close;
    run <<make "-j$*KERNEL.cpu-cores()" install>>;

    indir "$builddir/rakudo".IO, {
        run <make test>;
        run <make spectest>;
    }

    run(<patch -R -p1>, :in).in.spurt: $debug-nfg-patch, :close;

    run <<rm -rf "$builddir">>;
}

sub get-commits($old-version, :$subject) {
    run(
        'git',
        'log',
        '--reverse',
        '--no-merges',
        $subject ?? '--pretty=format:[%h] %s' !! '--pretty=format:%h',
        "$old-version..HEAD",
        :out,
    ).out.lines
}
