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

# https://github.com/aracpac

########################################################################################################################
# EDIT THESE VARIABLES TO SUIT YOUR NEEDS ##############################################################################
########################################################################################################################
########################################################################################################################
vagrantConfig = Hash.new
vagrantConfig[ "ip" ] = "192.168.10.10" # local ip for the box (used when 'private_network' is set to 'ip')
vagrantConfig[ "hostname" ] = "dev.local" # primary hostname for the box
vagrantConfig[ "aliases" ] = [ "admin.dev.local" ]; # additional hostnames for the box
vagrantConfig[ "remote_share_point" ] = "/var/www" # the remote share point mapped in the guest's /etc/exports
vagrantConfig[ "remote_share_point_windows" ] = "\\var\\www\\html" # on windows, the path must be escaped
vagrantConfig[ "local_share_point" ] = "./www" # the local mount point
vagrantConfig[ "local_share_point_windows" ] = "X:" # must correspond to an unmapped drive
########################################################################################################################
########################################################################################################################
# DO NOT EDIT PAST THIS POINT ##########################################################################################
########################################################################################################################

if Vagrant::Util::Platform.windows?
    $nfs_fix = <<-NFSFIX
    @ECHO OFF
    :: This sets the default NFS user to 1000, which maps to the vagrant user in the AracPac development box :::::::::::::::
    :: use a temporary vb script to rerun this script as an administrator
    set "params=%*"
    cd /d "%~dp0" && ( if exist "%temp%\\getadmin.vbs" del "%temp%\\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || (  echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~sdp0"" && %~s0 %params%", "", "runas", 1 >> "%temp%\\getadmin.vbs" && "%temp%\\getadmin.vbs" && exit /B )
    ECHO Enabling necessary windows features
    powershell Enable-WindowsOptionalFeature -Online -FeatureName ServicesForNFS-ClientOnly -All
    powershell Enable-WindowsOptionalFeature -Online -FeatureName ClientForNFS-Infrastructure -All
    powershell Enable-WindowsOptionalFeature -Online -FeatureName NFS-Administration -All
    ECHO Setting anonymous uid to 1000
    REG ADD HKLM\\Software\\Microsoft\\ClientForNFS\\CurrentVersion\\Default /f /v AnonymousUid /t REG_DWORD /d 1000
    ECHO Setting anonymous guid to 1000
    REG ADD HKLM\\Software\\Microsoft\\ClientForNFS\\CurrentVersion\\Default /f /v AnonymousGid /t REG_DWORD /d 1000
    ECHO Setting default windows filemode to 775
    nfsadmin client localhost config fileaccess=775
    ECHO Restarting the NFS Client
    net stop nfsclnt /y
    net stop nfsrdr /y
    net start nfsrdr /y
    net start nfsclnt /y
    ECHO Done!
    NFSFIX

    $nfsmount = <<-NFSMOUNT
    net use #{vagrantConfig[ "local_share_point_windows" ]} \\\\#{vagrantConfig[ "hostname" ]}#{vagrantConfig[ "remote_share_point" ]}
    NFSMOUNT

    $nfsumount = <<-NFSUMOUNT
    net use #{vagrantConfig[ "local_share_point_windows" ]} /delete /y
    NFSUMOUNT

    # create a batch file to fix nfs read-only issues on windows ()only needs to be run once per host machine)
    unless File.exist?( './nfs_fix.bat' )
        File.write( './nfs_fix.bat', $nfs_fix )
    end
else
    $nfsmount = <<-NFSMOUNT
    sudo mount -t nfs -o rw,rsize=8192,wsize=8192 #{vagrantConfig[ "ip" ]}:#{vagrantConfig[ "remote_share_point" ]} #{vagrantConfig[ "local_share_point" ]}
    NFSMOUNT

    $nfsumount = <<-NFSUMOUNT
    sudo umount -f #{vagrantConfig[ "local_share_point" ]}
    NFSUMOUNT

    # create the local mount point for the remote NFS folder if it doesn't exist
    unless File.exist?( vagrantConfig[ "local_share_point" ] )
        FileUtils.mkdir_p vagrantConfig[ "local_share_point" ]
    end
end

Vagrant.configure( "2" ) do |config|
    # configure vagrant hostmanager if it's installed
    if Vagrant.has_plugin?( "vagrant-hostmanager" )
        config.hostmanager.enabled = true
        config.hostmanager.manage_host = true
        config.hostmanager.manage_guest = true
        config.hostmanager.ignore_private_ip = false
        config.hostmanager.include_offline = true
    end
    # configure vagrant
    config.vm.box = "aracpac/ubuntu22"
    config.vm.box_version = ">=2.2.0"
    config.vm.define vagrantConfig[ "hostname" ] do |node|
        node.vm.hostname = vagrantConfig[ "hostname" ]
        node.vm.network "private_network", ip: vagrantConfig[ "ip" ]
        if Vagrant.has_plugin?( "vagrant-hostmanager" )
            if  !vagrantConfig[ "aliases" ].empty?
                node.hostmanager.aliases = vagrantConfig[ "aliases" ]
            end
        end
        # configure triggers to mount and unmount nfs share
        if Vagrant::Util::Platform.windows?
            node.trigger.after [ :up, :provision ] do |trigger|
                if `net use #{vagrantConfig[ "local_share_point_windows" ]} 2> nul` == ""
                    trigger.info = "Mounting NFS to #{vagrantConfig[ "local_share_point_windows" ]}"
                    trigger.run = { inline: $nfsmount }
                else
                    trigger.info = "#{vagrantConfig[ "local_share_point_windows" ]} is already mapped, skipping"
                end
            end
            node.trigger.after [ :destroy, :halt ] do |trigger|
                if `net use #{vagrantConfig[ "local_share_point_windows" ]} 2> nul` == ""
                    trigger.info = "#{vagrantConfig[ "local_share_point_windows" ]} is not mapped, skipping"
                else
                    trigger.info = "Unmounting NFS from #{vagrantConfig[ "local_share_point_windows" ]}"
                    trigger.run = { inline: $nfsumount }
                end
            end
        else
            node.trigger.after [ :up, :provision ] do |trigger|
                if `mount | grep #{File.expand_path vagrantConfig[ "local_share_point" ]}` == ""
                    trigger.info = "Mounting NFS to #{vagrantConfig[ "local_share_point" ]}"
                    trigger.run = { inline: $nfsmount }
                else
                    trigger.info = "#{vagrantConfig[ "local_share_point" ]} is already mounted, skipping"
                end
            end
            node.trigger.after [ :destroy, :halt ] do |trigger|
                if `mount | grep #{File.expand_path vagrantConfig[ "local_share_point" ]}` == ""
                    trigger.info = "#{vagrantConfig[ "local_share_point" ]} is not mounted, skipping"
                else
                    trigger.info = "Unmounting NFS from #{vagrantConfig[ "local_share_point" ]}"
                    trigger.run = { inline: $nfsumount }
                end
            end
        end
    end

    # uncomment to expose ports in the guest (vagrant) machine to your local network
    # config.vm.network "forwarded_port", guest: 80, host: 8080, id: "http", protocol: "tcp", auto_correct: true
    # config.vm.network "forwarded_port", guest: 443, host: 8443, id: "https", protocol: "tcp", auto_correct: true
    # config.vm.network "forwarded_port", guest: 3306, host: 13306, id: "mysql", protocol: "tcp", auto_correct: true

    # configure virtualbox
    config.vm.provider :virtualbox do |vb|
        vb.name = config.vm.hostname
        vb.gui = false
        # enable host i/o cache on the sata controller (see https://www.virtualbox.org/manual/ch05.html#iocaching)
        vb.customize ["storagectl", :id, "--name", "SATA Controller",  "--hostiocache", "on"]
        # use nameservers based on host machine. fixes broken /etc/resolv.conf (see https://www.virtualbox.org/manual/ch09.html#nat_host_resolver_proxy)
        vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
        vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
        # change network card type for better performance (see https://www.virtualbox.org/manual/ch06.html#nichardware)
        vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
        vb.customize ["modifyvm", :id, "--nictype2", "virtio" ]
        # enable pae/nx (see https://www.virtualbox.org/manual/ch03.html#settings-processor)
        vb.customize ["modifyvm", :id, "--pae", "on"]
        # enable kvm paravirtualization (see https://www.virtualbox.org/manual/ch10.html#gimproviders)
        vb.customize ["modifyvm", :id, "--paravirtprovider", "kvm"]
        # lower time sync threshold (see https://www.virtualbox.org/manual/ch09.html#idm8477)
        vb.customize [ "guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold", 1000 ]
        # 2 GB RAM, 2 CPUs, capped at 75% (see https://unix.stackexchange.com/a/325959/138364)
        vb.customize [ "modifyvm", :id, "--cpuexecutioncap", "75" ]
        vb.memory = 2048
        vb.cpus = 2
    end
end