#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Std;
use English;
use POSIX;
use Data::Dumper;

#
# A simple CLI wrapper around libvnode_docker::emulabizeImage; should
# only be used for testing or image import.
#
sub usage()
{
    print "Usage: emulabize-image [-d <level>] [-e <emulabizationlevel>]\n".
	  "         [-P pullpolicy] [-u user] [-p pass] [-D] image|dockerfile-url [newimagename]\n".
	  "\n".
          "  -d <level>  Debug mode\n" .
	  "  -e <level>  Emulabization level (none,basic,core,full,buildenv)\n".
	  "  -P <policy> Pull policy for base image (should we update to the\n".
	  "              latest, or use a locally-cached version).  Valid\n".
	  "              values: latest, cached\n".
	  "  -f          Update the new image even if it already exists,\n".
	  "              or if the base image has a new version\n".
	  "  -u <user>   A username to use to pull the base image\n".
	  "  -p <pass>   A password to use to pull the base image\n".
	  "  -h          Show this usage message.\n".
	  "  -D          First non-optional arg is a Dockerfile url, not an\n".
	  "              image repo:tag.  Requires the <newimagename> param\n".
	  "\n".
	  "<image> is the base image name; it will be pulled if it does not\n".
	  "already exist.  The optional <newimagename> argument will be used\n".
	  "as the new image name if it is specified; otherwise one will be\n".
	  "created for you.  So, if you specify 'ubuntu:16.04' as the base,\n".
	  "the new image name would be 'ubuntu-16.04:emulab-core' if you\n".
	  "didn't specify <newimagename>.\n";
    exit(1);
}
my $optlist = "hfd:e:P:u:p:D";
my $debug = 0;
my $emulabization;
my $pullpolicy;
my $update = 0;
my $user;
my $pass;
my $isdockerfile = 0;

#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
my %options = ();
if (!getopts($optlist,\%options)) {
    usage();
}
if (defined($options{"h"})) {
    usage();
}
if (defined($options{"f"})) {
    $update = 1;
}
if (defined($options{"d"})) {
    $debug = $options{"d"};
}
if (defined($options{"e"})) {
    $emulabization = $options{"e"};
}
if (defined($options{"P"})) {
    $pullpolicy = $options{"P"};
}
if (defined($options{"u"})) {
    $user = $options{"u"};
}
if (defined($options{"p"})) {
    $pass = $options{"p"};
}
if (defined($options{"D"})) {
    $isdockerfile = 1;
}
usage()
    if (@ARGV < 1 || @ARGV > 2);

my ($image,$newimageref) = @ARGV;
my $dockerfile;
if ($isdockerfile) {
    $dockerfile = $image;
    $image = $newimageref;
    if (!defined($image)) {
	warn("-D requires <newimagename>!");
	usage();
    }
    $newimageref = undef;
}

#
# Must be root.
# 
if ($UID != 0) {
    die("*** $0:\n".
	"    Must be root to run this script!\n");
}

#
# Turn off line buffering on output
#
$| = 1;

# Drag in path stuff so we can find emulab stuff.
BEGIN { require "/etc/emulab/paths.pm"; import emulabpaths; }

use libsetup;
use libvnode_docker;

TBDebugTimeStampsOn();
libvnode_docker::setDebug($debug);
my $newization;
my $rc = libvnode_docker::emulabizeImage(
    $image,\$newimageref,$emulabization,\$newization,$update,$pullpolicy,$user,$pass,$dockerfile);
if ($rc) {
    fatal("ERROR: failed to emulabize $image!\n");
}
else {
    print "Successfully emulabized $image: new image $newimageref".
	" (new emulabization $newization).\n";
}
exit(0);
