#!/usr/bin/env perl
use strict;
use warnings;
use Mojo::File 'tempfile';
use Mojo::JSON qw'decode_json encode_json';
use Mojo::ByteStream 'b';
use Mojo::UserAgent;

$ENV{MOJO_NO_JSON_XS} = 0;

our @ARGV;

my $JAVA8_HOME  = '/usr/lib/jvm/java-1.8.0-openjdk-amd64';
my $JAVA11_HOME = '/usr/lib/jvm/java-1.11.0-openjdk-amd64';
my $JAVA17_HOME = '/usr/lib/jvm/java-1.17.0-openjdk-amd64';
my $JAVA21_HOME = '/usr/lib/jvm/java-1.21.0-openjdk-amd64';

unless (-d $JAVA17_HOME) {
  $JAVA17_HOME = '/opt/java/jdk-17.0.2';
};

unless (-d $JAVA21_HOME) {
  $JAVA21_HOME = '/opt/java/jdk-21.0.0';
};

# Check which main branch exists locally
my $branches = `git branch --list main master`;
chomp $branches;

# Split into lines and clean up formatting (remove whitespace and asterisks)
my @branch_list = split /\n/, $branches;
@branch_list = map { s/^\s*\*?\s*//; $_ } @branch_list;

# Determine which branch to use (prefer main over master)
my $main_branch;
if (grep { $_ eq 'main' } @branch_list) {
    $main_branch = 'main';
} elsif (grep { $_ eq 'master' } @branch_list) {
    $main_branch = 'master';
} else {
    die "Error: Neither 'main' nor 'master' branch found locally\n";
}


my $url = $ARGV[0];

sub _check {
  my $cmd = shift;
 CHECK:
  print "\n\n" . 'Do "' . $cmd . '"? (y/n)', "\n";

  my $x = <STDIN>;
  chomp($x);
  if ($x eq 'y' || $x eq 'Y') {
    system $cmd;
  } elsif ($x eq 'n' || $x eq 'N') {
    exit;
  } else {
    print "Please answer with 'y' or 'n'.\n";
    goto CHECK;
  };
};

unless ($url) {
  print 'git_gerrit_pull https://github.com/KorAP/.../pull/..' . "\n";
  exit;
};

_check('git checkout ' . $main_branch);

_check('git pull origin ' . $main_branch);

$url =~ m!KorAP/([^/]+?)/pull/(\d+?)$!;

my $ua = Mojo::UserAgent->new;

print "Fetch $url...\n";

my $project = $1;
my $pr = $2;
my $pr_html = $ua->get($url)->res->dom;
my $branch = $pr_html->at('.commit-ref.head-ref');

# Legacy path
if ($branch) {
  $branch = $branch->all_text;
}

# JSON path
elsif (my $json = $pr_html->at('script[data-target=react-app.embeddedData]')) {

  $json = decode_json(b($json->all_text)->encode->to_string);

  $branch = $json
    ->{payload}
    ->{pullRequestsLayoutRoute}
    ->{pullRequest}
    ->{headBranch};

};

unless ($branch) {
  warn 'Unable to retrieve branch name';
  exit;
};

_check('git fetch github pull/' . $pr . '/head:' . $branch);
_check('git checkout ' . $branch);
_check('git rebase ' . $main_branch);


# Kustvakt
if ($project =~ m!^Kustvakt$!i) {
  _check('JAVA_HOME="'.$JAVA17_HOME.'" mvn clean test');
}

# KalamarExport-Plugin
elsif ($project =~ m!^Kalamar-Plugin-Export$!i) {
  _check('JAVA_HOME="'.$JAVA17_HOME.'" mvn clean test');
}

# Koral
elsif ($project =~ m!^Koral$!i) {
  _check('JAVA_HOME="'.$JAVA21_HOME.'" mvn clean test');
}

# Krill
elsif ($project =~ m!^Krill$!i) {
  _check('JAVA_HOME="'.$JAVA21_HOME.'" mvn clean test');
}

# Kalamar-Plugin-ExternalResources
elsif ($project =~ m!^Kalamar-Plugin-ExternalResources$!i) {
  _check('go test ./...');
}

# KorapSRU
elsif ($project =~ m!^KorapSRU$!i) {
  _check('JAVA_HOME="'.$JAVA8_HOME.'" mvn clean test');
}

# Korap-Tokenizer
elsif ($project =~ m!^KorAP-Tokenizer$!i) {
  _check('JAVA_HOME="'.$JAVA8_HOME.'" mvn clean test');
}

# Datok
elsif ($project =~ m!^Datok$!i) {
  _check('make test');
}

# Unknown Project
else {
  print "Unknown project $project!\n\n";
  exit(1);
};



_check('git commit --amend --no-edit');

{
  my $ret = `git log -1 --pretty=%B`;
  my $newret = '';
  my $change_id = '';
  my $first = 1;
  foreach my $line (split "\n", $ret) {
    if ($first) {
      chomp $line;
      $line .= " (closes #$pr)\n";
      $first = 0;
    }
    elsif ($line =~ /^Change-Id: /) {
      $change_id = $line;
      next;
    };
    $newret .= $line . "\n";
  };

  if ($change_id) {
    $newret .= "\n" . $change_id."\n\n";
  };

  my $msg_file = tempfile();
  $msg_file->spurt($newret);

  print "===================================\n";
  print $newret;
  print "===================================\n";

  _check('git commit -F ' . $msg_file . ' --amend');
};

_check('git push origin HEAD:refs/for/' . $main_branch);

_check('git checkout ' . $main_branch);
_check('git branch -D ' . $branch);

print "\n\nEverything done - thank you!\n\n"

__END__

=pod

This script is an alternative to C<import_github_pull_requests>
that ignores CI results on github and just requires the
URL of a specific GH pull request to send it through Gerrit.

Prerequisites:
Remote repository "github"
For Kustvakt and Koral Java 11 at /usr/lib/jvm/java-1.11.0-openjdk-amd6
For KorapSRU Java 8 at /usr/lib/jvm/java-1.8.0-openjdk-amd6
For KalamarExport-Plugin Java 17 at /usr/lib/jvm/java-17-openjdk-amd64 
