#!/bin/sh -E
VBSnap=vbsnap

Usage="`basename $0` base clone [port] [intnet2 intnet3 intnet4]"
die() { # Message [command]
  echo "$1" >&2
  test -z "$2" || eval $2 >&2
  echo -e "\nUsage:\n$Usage" >&2
  exit 1
}

Base="$1"
test -n "$Base" || die "No VM specified" "VBoxManage list vms"
Group="`VBoxManage showvminfo "$Base" | sed -En 's/^Groups:[[:space:]]+([^,[:space:]]+).*/\1/p'`"
ReGRoup="Groups:[[:space:]]+$Group(,|$)"
test -z "$Base" -o -z "$Group" && die "Unknown VM «$Base»" "VBoxManage list vms"
NGroup=`VBoxManage list -l vms | egrep "$ReGRoup" | wc -l`
shift
Name="$1"
# TODO show group
test -n "$Name" || {
  echo "Clones in group '$Group' ($Base):"
  VBoxManage list -l vms | sed -En "/^Name/h;\#$ReGRoup#{x;s/^Name:[[:space:]]*//p}"
  echo -e "\nUsage:\n$Usage" >&2
  exit 1
}
shift

Nets=""
NNet=2
Port=$((2300+NGroup))
for Par; do
  case "$Par" in
    [a-zA-Z]*) # Net
      Nets="$Nets --nic$NNet intnet --intnet$NNet $Par --cableconnected$NNet on"
      NNet=$((NNet+1))
      ;;
    ''|*[^0-9]*) die "Incorrent net name «$Par»" "VBoxManage list intnets" ;;
    *) # Port
      Port="$Par" ;;
  esac
done

VBoxManage snapshot "$Base" list | grep -q "Name: $VBSnap (UUID:.*" || {
  set -x
  VBoxManage snapshot "$Base" take "$VBSnap"
  set +x
}

HName="`echo $Name | tr -dc '[:alnum:]'`"
set -x
VBoxManage clonevm "$Base" --groups="$Group" --name="$Name" --options=Link --register --snapshot "$VBSnap"
VBoxManage modifyvm "$Name" --uartmode1 tcpserver $Port $Nets
VBoxManage setextradata "$Name" VBoxInternal/Devices/pcbios/0/Config/DmiSystemVendor "$HName"
set +x
