# frozen_string_literal: true

# Vagrant CAN NOT cohabitate well with bundler, # this bootstrap DOES NOT load any project sources. # This file is used as a kind of template. # “boxes“ variable is defined at runtime. # # @see Kamaze::Project::Tools::Vagrant

require 'pp' require 'pathname'

# requires ———————————————————– requires_from_boxes = lambda do |boxes|

pwd = ::Pathname.new(Dir.pwd)

[].tap do |requires|
  boxes.each do |box, box_config|
    requires.concat(box_config['requires'] || [])
  end
end.map do |req|
  req = pwd.join(req.to_s).realpath if pwd.join(req.to_s).file?
  require req.to_s
  req
end

end

# synced folders —————————————————– synced_folders_config = lambda do |config, box_config|

(box_config['synced_folders'] || []).each do |s|
  folders = s.delete(:folders)

  config.vm.synced_folder(*folders, **s)
end

end

# modifyvm config —————————————————- modifyvm_config = lambda do |config, box_config|

provider = box_config.fetch('provider')
modifyvm = box_config['modifyvm']

(modifyvm || []).each do |c|
  config.vm.provider(provider) do |v|
    c[0] = "--#{c[0]}" if c[0] and c[0].slice(0, 2) != '--'

    v.customize(['modifyvm', :id] + c.map(&:to_s))
  end
end

end

# machine config —————————————————– machine_config = lambda do |config, name, box_config, &block|

config.vm.define name, autostart: false do |machine|
  box, version = box_config.fetch('image').split(':')
  machine.vm.box = box
  machine.vm.box_version = version if version

  block&.call(machine)
end

end

# machine networks config ——————————————— machine_networks_config = lambda do |machine, box_config|

(box_config['networks'] || []).each do |c|
  machine.vm.network(*(c[0] || []), **(c[1] || {}))
end

end

# machine config vm ————————————————– # @see www.vagrantup.com/docs/vagrantfile/machine_settings.html machine_vm_config = lambda do |machine, box_config|

['guest', 'hostname', 'communicator'].each do |k|
  next unless box_config.member?(k)

  box_config.fetch(k).tap do |v|
    machine.vm.public_send("#{k}=", v)
  end
end

end

# machine provisions ————————————————- machine_provisions_config = lambda do |machine, box_config|

provisions = box_config['provisions']
(provisions || []).each do |provision|
  type = provision.delete(:type)&.to_s

  machine.vm.provision(type, **provision)
end

end

# @see github.com/guard/listen/wiki/Duplicate-directory-errors # # Listen >=2.8 # patch to silence duplicate directory errors. USE AT YOUR OWN RISK if YAML.safe_load(ENV.to_s)

require 'listen'

# rubocop:disable all
if Gem::Version.new(Listen::VERSION) >= Gem::Version.new('2.8.0')
  module Listen
    class Record
      class SymlinkDetector
        def _fail(_, _)
          fail Error, "Don't watch locally-symlinked directory twice"
        end
      end
    end
  end
end
# rubocop:enable all

end

# configure ———————————————————- Vagrant.configure(2) do |config|

requires_from_boxes.call(boxes)
boxes.each do |box, box_config|
  next if box_config['disabled']

  modifyvm_config.call(config, box_config)
  synced_folders_config.call(config, box_config)

  machine_config.call(config, box, box_config) do |machine|
    machine_networks_config.call(machine, box_config)
    machine_vm_config.call(machine, box_config)
    machine_provisions_config.call(machine, box_config)
  end
end

end