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

require 'yaml'

current_dir = File.dirname(File.expand_path(__FILE__))
testcase_file = "#{current_dir}/vagrant_testcase.yml"
ctlconf_file = "#{current_dir}/vagrant_ctlconf.yml"
if File.exist?(testcase_file)
  vagrant_config = YAML.load_file("#{testcase_file}")
  vagrant_ctlconfig = YAML.load_file("#{ctlconf_file}")
  #vagrant_devs = ["/dev/sda", "/dev/sdb", "/dev/sdc"]
  vagrant_box_url = vagrant_config['box_url']
  if vagrant_config['local_boxes'] or vagrant_config['box_url'] === "local"
    vagrant_url_local_base = ENV['VAGRANT_BOXES_URL'] ? ENV['VAGRANT_BOXES_URL'] : "file:///vagrant_boxes/"
    vagrant_box_filename = "virtualbox-" + vagrant_config['box'].to_s.gsub(/\//, "-") + ".box"
    vagrant_box_url = vagrant_url_local_base + vagrant_box_filename
  end
  Vagrant.configure("2") do |config|
    config.vm.box_check_update = true
    config.ssh.insert_key = false

    if Vagrant.has_plugin?("vagrant-proxyconf")
      config.proxy.enabled = false
    end

    config.vm.define 'test-host' do |testmachine|
      testmachine.vm.box = vagrant_config['box']
      testmachine.vm.box_url = vagrant_box_url
      testmachine.vm.box_check_update = true
      testmachine.vagrant.plugins = ["vagrant-vbguest", "vagrant-registration"]
      testmachine.vbguest.no_remote = true
      testmachine.vbguest.auto_update = vagrant_config['vbguest_update'] || false
      # Will trigger reboot if necessary (required for centos images at least)
      testmachine.vbguest.installer_options = { allow_kernel_upgrade: vagrant_config['vbguest_update'] }
      testmachine.vm.network :forwarded_port, guest: 22, host: 2223, id: "ssh"
      testmachine.vm.network "private_network", ip: "192.168.56.21", virtualbox__intnet: true
      testmachine.vm.synced_folder ".", "/vagrant", disabled: true
      testmachine.vm.provider "virtualbox" do |vb|
        # docker_disk = 'extra_disk/docker_disk.vdi'
        # unless File.exist?(docker_disk)
        #   vb.customize ['createhd', '--filename', docker_disk, '--size', 5 * 1024]
        # end
        # vb.customize ['storageattach', :id, '--storagectl', vagrant_config['storage_ctl'], '--port', vagrant_config['storage_port'], '--device', 0, '--type', 'hdd', '--medium', docker_disk]

        mem_divisor = 2
        cpu_divisor = 2
        host = RbConfig::CONFIG['host_os']
        if host =~ /darwin|bsd/
          cpus = `sysctl -n hw.ncpu`.to_i
          mem = `sysctl -n hw.memsize`.to_i / 1024 / 1024
        elsif host =~ /linux/
          cpus = `nproc`.to_i
          mem = `grep 'MemTotal' /proc/meminfo | sed -e 's/MemTotal://' -e 's/ kB//'`.to_i / 1024
        elsif host =~ /mswin|mingw/
          cpus = `wmic CPU Get NumberOfLogicalProcessors /Value`.strip.split('=')[1].to_i
          mem = `wmic ComputerSystem Get TotalPhysicalMemory /Value`.strip.split('=')[1].to_i / 1024 / 1024
        else
          cpus = 1
          mem = 2048
        end

        if cpus > 2
          cpus = cpus / cpu_divisor
        end

        if mem > 4096
          mem = mem / mem_divisor
        end

        vb.customize ["modifyvm", :id, "--memory", mem]
        vb.customize ["modifyvm", :id, "--cpus", cpus]
        vb.customize ["modifyvm", :id, "--audio", "none"]
        vb.customize ["modifyvm", :id, "--hwvirtex", "on"]
        vb.customize ["modifyvm", :id, "--nested-hw-virt", "on"]
      end

      if Vagrant.has_plugin?('vagrant-registration')
        if vagrant_config['box'].include? "rhel"
          testmachine.registration.name = "ansible-role-docker-ce"
          if "#{ENV['RHSM_ACTIVATIONKEY']}" === ""
            testmachine.registration.username = "#{ENV['RHSM_USERNAME']}"
            testmachine.registration.password = "#{ENV['RHSM_PASSWORD']}"
          else
            testmachine.registration.org = "#{ENV['RHSM_ORG']}"
            testmachine.registration.activationkey = "#{ENV['RHSM_ACTIVATIONKEY']}"
          end
        else
          testmachine.registration.skip = true
        end
      end
    end

    config.vm.define 'controller', primary: true do |machine|
      machine.vm.box = vagrant_ctlconfig['controller_box']
      machine.vm.box_check_update = true
      machine.vagrant.plugins = ["vagrant-vbguest", "vagrant-host-shell"]
      machine.vbguest.auto_update = false
      machine.vbguest.no_remote = true
      machine.vbguest.installer = "VagrantVbguest::Installers::RedHat"
      machine.vbguest.installer_hooks[:before_install] = ["dnf install -y kernel-devel kernel-headers"]
      # machine.vbguest.installer_hooks[:before_install] = ["dnf upgrade -y && dnf install -y kernel-devel-$(uname -r) kernel-headers-$(uname -r)"]
      machine.vbguest.installer_arguments = ['--nox11']
      machine.vm.synced_folder ".", "/vagrant", :mount_options => ["rw"]
      #machine.vm.synced_folder "../", "/mnt/#{vagrant_ctlconfig['role_dir']}", :mount_options => ["ro"]
      machine.vm.synced_folder "../", "/mnt", :mount_options => ["ro"]
      machine.vm.network :forwarded_port, guest: 22, host: 2222, id: "ssh"
      machine.vm.network "private_network", ip: "192.168.56.11", virtualbox__intnet: true
      machine.vm.provider "virtualbox" do |vb|
        vb.customize ["modifyvm", :id, "--audio", "none"]
      end

      # Prepare Ansible roles directory
      machine.vm.provision "shell",
        inline: "test -d /etc/ansible/roles/#{vagrant_ctlconfig['galaxy_role_name']} || \
          (mkdir -p /etc/ansible/roles && \
          ln -s /mnt /etc/ansible/roles/#{vagrant_ctlconfig['galaxy_role_name']})"

      machine.vm.provision "shell",
        inline: "test -e /home/vagrant/.ssh/id_rsa || (mkdir -p /home/vagrant/.ssh && chmod 0700 /home/vagrant/.ssh && \
          curl -s https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant > /home/vagrant/.ssh/id_rsa && \
          chmod 0600 /home/vagrant/.ssh/id_rsa && chown -R vagrant:vagrant /home/vagrant/.ssh)"

      machine.vm.provision "shell",
      inline: "dnf -y install epel-release && dnf clean all && dnf makecache"

      # machine.vm.provision "shell",
      # inline: "dnf -y update"

      machine.vm.provision "shell",
      inline: "dnf -y install curl gcc libffi-devel openssl-devel haveged sshpass"

      if vagrant_ctlconfig['controller_py3_install'] === true
        machine.vm.provision "shell",
        inline: "dnf -y install python3.12-pip python3.12-devel python3.12-setuptools"

        machine.vm.provision "shell",
        inline: "pip3.12 install ansible==#{vagrant_ctlconfig['ansible_version']}"
      else
        machine.vm.provision "shell",
        inline: "dnf -y install python3-devel python3-setuptools"

        machine.vm.provision "shell",
        inline: "pip3 install ansible==#{vagrant_ctlconfig['ansible_version']}"
      end

      # Prepare
      machine.vm.provision "ansible_local" do |ansible|
        ansible.install = false
        ansible.compatibility_mode = "2.0"
        ansible.galaxy_role_file  = "requirements.yml"
        ansible.galaxy_roles_path = '/var/tmp/roles'
        # To avoid installing roles multiple times when running regession testing
        ansible.galaxy_command = "test -d /var/tmp/roles || sudo /usr/local/bin/ansible-galaxy install --role-file=%{role_file} --roles-path=%{roles_path} --force"
        ansible.playbook = vagrant_ctlconfig['prep_yml'] || "prepare.yml"
        ansible.limit = "test-host"
        ansible.inventory_path = "hosts"
        ansible.config_file = "/vagrant/ansible.cfg"
        ansible.raw_arguments = ["#{ENV['ANSIBLE_ARG_0']}"]
        # ansible.extra_vars = {
        #   lvm_device: "#{vagrant_devs[vagrant_ctlconfig['storage_port']]}"
        # }
      end

      # Cannot trigger reboot via Ansible since Vagrant do network changes
      if vagrant_config['reboot'] === true
        machine.vm.provision :host_shell do |host_shell|
          host_shell.inline = 'vagrant reload test-host'
        end
      end
      # Test
      machine.vm.provision "ansible_local" do |ansible|
        ansible.install = false
        ansible.compatibility_mode = "2.0"
        ansible.playbook = vagrant_config['test_yml']
        ansible.limit = "test-host"
        ansible.inventory_path = "hosts"
        ansible.config_file = "/vagrant/ansible.cfg"
        ansible.raw_arguments = ["#{ENV['ANSIBLE_ARG_0']}"]
        # ansible.extra_vars = {
        #   lvm_device: "#{vagrant_devs[vagrant_config['storage_port']]}"
        # }
      end
    end

  end
else
  puts "==> test: File does not exist: #{testcase_file}!"
end
