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

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.

require "yaml"
load "lib/machine.rb"
load "lib/vd_utils.rb"

if not VdUtils.vagrant_experimentals.include?("disks")
  ENV["VAGRANT_EXPERIMENTAL"] =
    VdUtils.vagrant_experimentals.append("disks").join(",")
end

vd_config = YAML.load(open("machines.yml"))

ssh_pub_key = VdUtils.ssh_pub_key(vd_config)
machines = Machines.new(vd_config["machines"])

# TODO(yasufum) Test libvirt's boxes can be deployed haven't been tested yet.
supported_boxes = {
  "virtualbox" => {
    "ubuntu" => ["bento/ubuntu-24.04", "generic/ubuntu2404"]
  }
}

lvm_boxes = ["bento/ubuntu-24.04"]

Vagrant.configure("2") do |config|

  machines.each do |machine|
    config.vm.define machine.hostname do |server|
      server.vm.box = machine.box
      server.vm.hostname = machine.hostname

      #server.vm.box_check_update = false

      machine.private_ips.each do |ipaddr|
        server.vm.network "private_network", ip: ipaddr
      end

      if machine.public_ips != nil
        machine.public_ips.each do |ipaddr|
          server.vm.network "public_network", ip: ipaddr
        end
      end

      if machine.fwd_port_list != nil
        machine.fwd_port_list.each do |fp|
          ["tcp", "udp"].each do |prot|
            server.vm.network "forwarded_port",
                guest: fp["guest"], host: fp["host"],
                auto_correct: true, protocol: prot
          end
        end
      end

      if Vagrant.has_plugin?("vagrant-proxyconf")
        server.proxy.http = ENV["http_proxy"]
        server.proxy.https = ENV["https_proxy"]
        if ENV["no_proxy"] != nil
          server.proxy.no_proxy = ENV["no_proxy"] +
              "," + machine.private_ips.join(",")
        end
      end

      # Expand disk size for some images have not enough disk space.
      # NOTE: Two scenarios are expected, having logical volumes or not.
      #   For lvm case, add a virtual disk with an experimental feature first,
      #   create a logical volume then while provisioning later.
      # Add a virtual disk has arbitrary name.
      # TODO(yasufum): Fix the total amount of disk size will be over
      # `machine.disk_size` GB unexpectedly.
      if (VdUtils.is_disks_enabled(machine.provider) and
        lvm_boxes.include?(machine.box) and
        supported_boxes["virtualbox"]["ubuntu"].include?(machine.box))
        server.vm.disk :disk, size: "#{machine.disk_size}GB", name: "mydrive"
      else  # Not a case using lvm for which just resizing.
        if Vagrant.has_plugin?("vagrant-disksize")
          server.disksize.size = "#{machine.disk_size}GB"
        end
      end

      if machine.ssh_forward_x11 == true
        server.ssh.forward_x11 = true
      end

      server.vm.provider machine.provider do |vb|
      #   # Display the VirtualBox GUI when booting the machine
      #   vb.gui = true
      #
      #   # Customize the amount of memory on the VM:
        #vb.customize ["modifyhd", "disk id", "--resize", "size in megabytes"]
        vb.cpus = "#{machine.nof_cpus}"
        vb.memory = "#{machine.mem_size * 1024}"
      end

      # Add stack user and register ssh key for direct login with.
      server.vm.provision "shell", inline: <<-SHELL
        useradd -s /bin/bash -d /opt/stack -m stack
        echo "stack ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/stack

        mkdir -p /opt/stack/.ssh
        echo "#{ssh_pub_key}" >> /opt/stack/.ssh/authorized_keys
        chown -R stack:stack /opt/stack/.ssh
      SHELL

      # Expand disk space.
      # NOTE: The name of devices and volumes are depend on the box images.
      if (VdUtils.is_disks_enabled(machine.provider) and
      lvm_boxes.include?(machine.box) and
      supported_boxes["virtualbox"]["ubuntu"].include?(machine.box))
        server.vm.provision "shell", inline: <<-SHELL
          pvcreate /dev/sdb
          vgextend ubuntu-vg /dev/sdb
          lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
          resize2fs /dev/ubuntu-vg/ubuntu-lv
        SHELL
      end

      VdUtils.setup_git_config
      VdUtils.setup_ssh_config(vd_config)
    end
  end
end
