#!/usr/bin/perl

use strict;
use warnings;

use File::Basename;

my $fd = $ENV{APT_HOOK_INFO_FD};
my $check_file = '/please-remove-proxmox-ve';
my $check_package = 'proxmox-ve';
my $hook_name = basename($0);

my $log = sub {
  my ($line) = @_;
  print "W: ($hook_name) $line";
};

if (!defined $fd || $fd == 0 || $fd !~ /^\d+$/) {
  $log->("APT_HOOK_INFO_FD not correctly defined, skipping apt-pve-hook checks\n");
  exit 0;
}

open(my $fh, "<&=", $fd) or die "E: could not open APT_HOOK_INFO_FD (${fd}) - $!\n";

my $cleanup = sub {
  my ($rc, $confirm) = @_;

  close($fh);

  if ($confirm) {
      my $line = <STDIN>;
  }

  exit $rc;
};

my $file_read_firstline = sub {
    my ($filename) = @_;

    my $fh = IO::File->new($filename, "r");
    return undef if !$fh;
    my $res = <$fh>;
    chomp $res if $res;
    $fh->close;
    return $res;
};

chomp (my $ver = <$fh>);
if ($ver ne "VERSION 2") {
  $log->("apt-pve-hook misconfigured, expecting hook protocol version 2\n");
  $cleanup->(0);
}

my $blank;
while (my $line = <$fh>) {
  chomp $line;

  if (!defined($blank)) {
    $blank = 1 if !$line;
    next;
  }

  my ($pkg, $old, $dir, $new, $action) = (split / /, $line, 5);
  if (!defined($action)) {
    $log->("apt-pve-hook encountered unexpected line: $line\n");
    next;
  }

  if ($pkg eq 'proxmox-ve') {
    if ($action eq '**REMOVE**') {
      if (-e $check_file) {
        $log->("'$check_file' exists, proceeding with removal of package '${check_package}'\n");
        unlink $check_file;
      } else {
        $log->("!! WARNING !!\n");
        $log->("You are attempting to remove the meta-package '${check_package}'!\n");
        $log->("\n");
        $log->("If you really want to permanently remove '${check_package}' from your system, run the following command\n");
        $log->("\ttouch '${check_file}'\n");
        $log->("run apt purge ${check_package} to remove the meta-package\n");
        $log->("and repeat your apt invocation.\n");
        $log->("\n");
        $log->("If you are unsure why '$check_package' would be removed, please verify\n");
        $log->("\t- your APT repository settings\n");
        $log->("\t- that you are using 'apt full-upgrade' to upgrade your system\n");
        $cleanup->(1);
      }
    } elsif ($action eq '**CONFIGURE**' && $dir eq '<' && $old =~ /^6\./ && $new =~ /^7\./) {
      $log->("!! ATTENTION !!\n");
      $log->("You are attempting to upgrade from proxmox-ve '$old' to proxmox-ve '$new'. Please make sure to read the Upgrade notes at\n");
      $log->("\thttps://pve.proxmox.com/wiki/Upgrade_from_6.x_to_7.0\n");
      $log->("before proceeding with this operation.\n");
      $log->("\n");
      $log->("Press enter to continue, or C^c to abort.\n");
      $cleanup->(0, 1);
    }
  }
  if ($pkg =~ /^pve-kernel-/) {
    if ($action eq '**REMOVE**') {
      my $next_boot_ver = $file_read_firstline->("/etc/kernel/next-boot-pin");
      my $pinned_ver = $file_read_firstline->("/etc/kernel/proxmox-boot-pin");
      my $remove_pinned_ver = ($next_boot_ver && $pkg =~ /$next_boot_ver$/);
      $remove_pinned_ver ||= ($pinned_ver && $pkg =~ /$pinned_ver$/);
      if ($remove_pinned_ver) {
        $log->("!! WARNING !!\n");
        $log->("You are attempting to remove the currently pinned kernel '${pkg}'!\n");
        $log->("\n");
        $log->("If you really do not need the version anymore unpin it by running\n");
        $log->("\tproxmox-boot-tool kernel unpin'\n");
        $log->("and repeat your apt invocation.\n");
        $cleanup->(1);
      }
    }
  }
}

$cleanup->(0);
