#
#  Licensed to the Apache Software Foundation (ASF) under one or more
#  contributor license agreements.  See the NOTICE file distributed with
#  this work for additional information regarding copyright ownership.
#  The ASF licenses this file to You under the Apache License, Version 2.0
#  (the "License"); you may not use this file except in compliance with
#  the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#
require 'getoptlong'

ansibleTags=''
ansibleSkipTags='sensors'

begin
   opts = GetoptLong.new(
     [ '--ansible-tags', GetoptLong::OPTIONAL_ARGUMENT ],
     [ '--ansible-skip-tags', GetoptLong::OPTIONAL_ARGUMENT ]
   )

   opts.quiet = true

   opts.each do |opt, arg|
     case opt
       when '--ansible-tags'
         ansibleTags=arg
       when '--ansible-skip-tags'
         ansibleSkipTags=arg
     end
   end
rescue Exception => ignored
#Ignore to allow other opts to be passed to Vagrant
end

puts " Running with ansible-tags: " + ansibleTags.split(",").to_s if ansibleTags != ''
puts " Running with ansible-skip-tags: " + ansibleSkipTags.split(",").to_s if ansibleSkipTags != ''

hosts = [{
    hostname: "node1",
    ip: "192.168.66.121",
    memory: "8192",
    cpus: 4,
    promisc: 2  # enables promisc on the 'Nth' network interface
}]

Vagrant.configure(2) do |config|

  # host runs ubuntu
  config.vm.box = "ubuntu/trusty64"
  config.ssh.insert_key = true

  # enable the hostmanager plugin
  config.hostmanager.enabled = true
  config.hostmanager.manage_host = true

  # enable vagrant cachier if present
  if Vagrant.has_plugin?("vagrant-cachier")
    config.cache.enable :apt
    config.cache.scope = :box

    config.cache.synced_folder_opts = {
      type: :nfs,
      mount_options: ['rw', 'vers=3', 'tcp', 'nolock']
    }
  end

  # host definition
  hosts.each_with_index do |host, index|
    config.vm.define host[:hostname] do |node|

      # host settings
      node.vm.hostname = host[:hostname]
      node.vm.network "private_network", ip: host[:ip]

      # vm settings
      node.vm.provider "virtualbox" do |vb|
        vb.memory = host[:memory]
        vb.cpus = host[:cpus]
        # disable audio, so that the vm doesn't capture the sound / mic
        vb.customize ["modifyvm", :id, "--audio", "none"]
      end
    end
  end

  # provision the host with ansible
  config.vm.provision :ansible do |ansible|
    ansible.playbook = "ansible/playbook.yml"
    ansible.become = true
    ansible.tags = ansibleTags.split(",") if ansibleTags != ''
    ansible.skip_tags = ansibleSkipTags.split(",") if ansibleSkipTags != ''
    ansible.inventory_path = "ansible/inventory"
    ansible.compatibility_mode = "auto"
    ansible.raw_arguments = Shellwords.shellsplit(ENV['ANSIBLE_ARGS']) if ENV['ANSIBLE_ARGS']
  end
end
