# -*- mode: ruby -*-
# vi: set ft=ruby :

# CAUTION: DO NOT MAKE CHANGES TO THIS FILE. The vagrant-spk upgradevm process will overwrite it.

# Guess at a reasonable name for the VM based on the folder vagrant-spk is
# run from.  The timestamp is there to avoid conflicts if you have multiple
# folders with the same name.
VM_NAME = File.basename(File.dirname(File.dirname(__FILE__))) + "_sandstorm_#{Time.now.utc.to_i}"

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

# ugly hack to prevent hashicorp's bitrot. See https://github.com/hashicorp/vagrant/issues/9442
# this setting is required for pre-2.0 vagrant, but causes an error as of 2.0.3,
# remove entirely when confident nobody uses vagrant 1.x for anything.
unless Vagrant::DEFAULT_SERVER_URL.frozen?
  Vagrant::DEFAULT_SERVER_URL.replace('https://vagrantcloud.com')
end

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # Base on a 64-bit Debian box with vboxsf support (ex. contrib-buster64, bullseye64)
  config.vm.box = "debian/bookworm64"
  config.vm.post_up_message = "Your virtual server is running at: http://local.sandstorm.io:6090"


  if Vagrant.has_plugin?("vagrant-vbguest") then
    # vagrant-vbguest is a Vagrant plugin that upgrades
    # the version of VirtualBox Guest Additions within each
    # guest. If you have the vagrant-vbguest plugin, then it
    # needs to know how to compile kernel modules, etc., and so
    # we give it this hint about operating system type.
    config.vm.guest = "debian"
    config.vbguest.auto_update = false
  end

  # We forward port 6090, the vagrant-spk web port, so that developers can
  # visit their Sandstorm app from their browser as local.sandstorm.io:6090
  # (aka 127.0.0.1:6090).
  config.vm.network :forwarded_port, guest: 6090, host: 6090, host_ip: "127.0.0.1"

  # Use a shell script to "provision" the box. This installs Sandstorm using
  # the bundled installer.
  config.vm.provision "shell", inline: "sudo bash /opt/app/.sandstorm/global-setup.sh", keep_color: true
  # Then, do stack-specific and app-specific setup.
  config.vm.provision "shell", inline: "sudo bash /opt/app/.sandstorm/setup.sh", keep_color: true

  # Shared folders are configured per-provider since vboxsf can't handle >4096 open files,
  # NFS requires privilege escalation every time you bring a VM up,
  # and 9p is only available on libvirt.

  # Calculate the number of CPUs and the amount of RAM the system has,
  # in a platform-dependent way; further logic below.
  cpus = nil
  total_kB_ram = nil

  host = RbConfig::CONFIG['host_os']
  if host =~ /darwin/
    cpus = `sysctl -n hw.ncpu`.to_i
    total_kB_ram =  `sysctl -n hw.memsize`.to_i / 1024
  elsif host =~ /linux/
    cpus = `nproc`.to_i
    total_kB_ram = `grep MemTotal /proc/meminfo | awk '{print $2}'`.to_i
  elsif host =~ /mingw/
    cpus = `powershell -Command "(Get-WmiObject Win32_Processor -Property NumberOfLogicalProcessors | Select-Object -Property NumberOfLogicalProcessors | Measure-Object NumberOfLogicalProcessors -Sum).Sum"`.to_i
    total_kB_ram = `powershell -Command "[math]::Round((Get-WmiObject -Class Win32_ComputerSystem).TotalPhysicalMemory)"`.to_i / 1024
  end
  # Use the same number of CPUs within Vagrant as the system, with 1
  # as a default.
  #
  # Use at least 512MB of RAM, and if the system has more than 2GB of
  # RAM, use 1/4 of the system RAM. This seems a reasonable compromise
  # between having the Vagrant guest operating system not run out of
  # RAM entirely (which it basically would if we went much lower than
  # 512MB) and also allowing it to use up a healthily large amount of
  # RAM so it can run faster on systems that can afford it.
  if cpus.nil? or cpus.zero?
    cpus = 1
  end
  if total_kB_ram.nil? or total_kB_ram < 2048000
    assign_ram_mb = 512
  else
    assign_ram_mb = (total_kB_ram / 1024 / 4)
  end
  # Actually apply these CPU/memory values to the providers.
  config.vm.provider :virtualbox do |vb, override|
    vb.cpus = cpus
    vb.memory = assign_ram_mb
    vb.name = VM_NAME
    vb.customize ["modifyvm", :id, "--nictype1", "Am79C973"]

    # /opt/app and /host-dot-sandstorm are used by vagrant-spk
    override.vm.synced_folder "..", "/opt/app"
    override.vm.synced_folder ENV["HOME"] + "/.sandstorm", "/host-dot-sandstorm", mount_options: ["x-systemd.automount"]
    # /vagrant is not used by vagrant-spk; we need this line so it gets disabled; if we removed the
    # line, vagrant would automatically insert a synced folder in /vagrant, which is not what we want.
    override.vm.synced_folder "..", "/vagrant", disabled: true
  end
  config.vm.provider :libvirt do |libvirt, override|
    libvirt.cpus = cpus
    libvirt.memory = assign_ram_mb
    libvirt.default_prefix = VM_NAME

    # /opt/app and /host-dot-sandstorm are used by vagrant-spk
    override.vm.synced_folder "..", "/opt/app", type: "9p", accessmode: "passthrough"
    override.vm.synced_folder ENV["HOME"] + "/.sandstorm", "/host-dot-sandstorm", type: "9p", accessmode: "passthrough"
    # /vagrant is not used by vagrant-spk; we need this line so it gets disabled; if we removed the
    # line, vagrant would automatically insert a synced folder in /vagrant, which is not what we want.
    override.vm.synced_folder "..", "/vagrant", type: "9p", accessmode: "passthrough", disabled: true
  end
end
