#!/usr/bin/env perl
# setmibdev - use a seperate snmp module that's just for
# netdisco mib development

use strict;
use warnings;

use charnames ':full';
binmode STDOUT, ':utf8';
$|++;

use File::Temp;
use File::Path ();
use Time::HiRes 'sleep';
use Term::ANSIColor qw(:constants);
use File::Spec::Functions qw(splitdir catfile);
use IPC::Open3 'open3';
use POSIX qw(:sys_wait_h);

use FindBin;
use lib catfile($FindBin::Bin, 'lib');
use Helpers;

# Alien::SNMP builds an unpatched net-snmp; stock 5.9.1+ is enough for this
# bundle, so this only matters for a newer net-snmp or an isolated perl
our $MINALIENVERSION = '4.0509050202';
our $MINNETSNMP = '5.9.1';
my $home = "$ENV{MIBHOME}/EXTRAS/net-snmp.local";
my $localenv = "$home/bin/localenv";
my $cpanm = 'cpanm --quiet --notest';
my $success = "$home/.success_alien_snmp";

my $system_version = netsnmp_version();
if (netsnmp_version_at_least($system_version, $MINNETSNMP)) {
  print "\N{INFORMATION SOURCE} System net-snmp $system_version is already usable;",
    " setmibdev is only needed for a newer net-snmp or an isolated perl.\n";
}

if (not -e $success) {
  File::Path::remove_tree($home);
  mkdir $home;

  bld(
    qq{ curl -sL https://cpanmin.us/ | perl - --quiet --notest --local-lib-contained '$home' }
    .q{ App::cpanminus App::local::lib::helper }, 'cpanminus');

  bld(qq{ '$localenv' $cpanm 'Alien::SNMP~>=$MINALIENVERSION' }, 'net-snmp');

  open(my $ok, '>', $success) or die $!;  close $ok;
}

my $bindir = qx('$localenv' perl -MAlien::SNMP -e 'print Alien::SNMP->bin_dir');
my $built = qx('$bindir/snmptranslate' -V 2>&1);
$built =~ s/\s+$//;
print "\N{HEAVY CHECK MARK} Entering localenv ($built)...\n";
print "  To rebuild with the newest Alien::SNMP, remove $home first.\n";
exec(qq{'$localenv' $ENV{SHELL} -c 'export PATH="$bindir:\$PATH";\$SHELL'});

sub bld {
  my $target = shift || return;
  my $alias  = shift || return;
  my $out = File::Temp->new();
  my $err = File::Temp->new();
  my $in  = '';

  my $pid = open3($in, $out, $err, $target);
  while (! waitpid($pid, WNOHANG)) {
    status("Building $alias...");
    sleep 0.05;
  }
  my $child_exit_status = $? >> 8;
  seek($_, 0, 0) for ($out, $err);
  ($out, $err) = (<$out>, <$err>);

  blank();
  if ($child_exit_status) {
    print RED, "\N{HEAVY BALLOT X} ", CYAN,
      "Errors from $alias build:\n", RESET;
    print $out, "\n---\n" if $out;
    print $err, "\n---\n" if $err;
    exit 1;
  }

  return $out;
}
