winrm_username = "vagrant"
winrm_password = ENV.fetch "WINRM_PASSWORD" do
  puts "WINRM_PASSWORD not set, using 'vagrant'"
  "vagrant"
end

access_key_id = ENV.fetch "AWS_ACCESS_KEY" do
  puts "AWS_ACCESS_KEY not set"
  nil
end
secret_key_id = ENV.fetch "AWS_SECRET_KEY" do
  puts "AWS_SECRET_KEY not set"
  nil
end
subnet_id = ENV.fetch "AWS_SUBNET" do
  puts "AWS_SUBNET not set"
  nil
end
ami_id = ENV.fetch "AWS_AMI_ID" do
  puts "AWS_AMI_ID not set"
  nil
end
keypair_name = ENV.fetch "KEYPAIR_NAME" do
  puts "KEYPAIR_NAME not set"
  nil
end
private_key_path = ENV.fetch "PRIVATE_KEY_PATH" do
	puts "PRIVATE_KEY_PATH not set"
	nil
end

os_version = ENV.fetch "WINDOWS_OS_VERSION" do
  puts "WINDOWS_OS_VERSION not set"
  nil
end

configure_security_settings = <<-SHELL
  Set-ExecutionPolicy -ExecutionPolicy Bypass
SHELL

extract_fixtures_archive = <<-SHELL
  Push-Location "C:\\bosh"
    if (-Not (Test-Path ".\\tar.exe")) {
      Write-Error "Missing tar.exe"
      Exit 1
    }
    if (-Not (Test-Path ".\\fixtures.tgz")) {
      Write-Error "Missing fixtures.tgz"
      Exit 1
    }
    .\\tar.exe -xzf fixtures.tgz
    Move-Item -Path pipe.exe -Destination C:\\var\\vcap\\bosh\\bin\\pipe.exe
    Remove-Item fixtures.tgz
  Pop-Location
SHELL

apply_default_agent_config = <<-SHELL
  Copy-Item C:\\bosh\\agent-configuration\\agent.json C:\\bosh\\agent.json -Force
  Copy-Item C:\\bosh\\agent-configuration\\root-disk-settings.json C:\\bosh\\settings.json -Force
SHELL

reset_bosh_directory = <<-SHELL
  if ((Test-Path c:\\bosh\\service_wrapper.exe) -And ($(C:\\bosh\\service_wrapper.exe status) -ne "NonExistent")) {
    if ($(C:\\bosh\\service_wrapper.exe status) -eq "Started") {
      C:\\bosh\\service_wrapper.exe stop
    }

    C:\\bosh\\service_wrapper.exe uninstall
  }

  if (Test-Path C:\\bosh){
    Remove-Item -Recurse -Path C:\\bosh -Force
  }

  if (Test-Path C:\\var\\vcap\\bosh){
    Remove-Item -Recurse -Path C:\\var\\vcap\\bosh\\bin -Force
  }

  New-Item -ItemType 'directory' -Path C:\\bosh -Force
  New-Item -ItemType 'directory' -Path C:\\var\\vcap\\bosh\\bin -Force
  New-Item -ItemType 'directory' -Path C:\\var\\vcap\\bosh\\log -Force
SHELL

add_bosh_to_path = <<-SHELL
if ((Get-Command "bosh-agent.exe" -ErrorAction SilentlyContinue) -eq $null)
{
  $OldPath=(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment' -Name PATH).Path
  $AddedFolder='C:\\bosh'
  $NewPath=$OldPath+';'+$AddedFolder
  Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment' -Name PATH -Value $newPath
}
SHELL

put_modules_in_path = <<-SHELL
  Move-Item C:\\bosh\\psFixture 'C:\\Program Files\\WindowsPowerShell\\Modules'
SHELL

initialize_agent_service = <<-SHELL
  Move-Item C:\\bosh\\job-service-wrapper.exe C:\\var\\vcap\\bosh\\bin\\job-service-wrapper.exe -Force

  C:\\bosh\\service_wrapper.exe install
  C:\\bosh\\service_wrapper.exe start
SHELL

setup_aws_winrm_user = <<-SHELL
  <powershell>
  net user #{winrm_username} #{winrm_password} /ADD
  net localgroup administrators #{winrm_username} /ADD
  net localgroup WinRMRemoteWMIUsers__ #{winrm_username} /ADD

  winrm set winrm/config/service '@{AllowUnencrypted="true"}'
  winrm set winrm/config/service/auth '@{Basic="true"}'
  winrm set winrm/config/winrs '@{MaxShellsPerUser="100"}'
  winrm set winrm/config/winrs '@{MaxConcurrentUsers="30"}'
  winrm set winrm/config/winrs '@{MaxProcessesPerShell="100"}'
  winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}'
  winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="5000"}'
  netsh advfirewall set publicprofile state off
  </powershell>
SHELL

start_nats = <<-SHELL
  rm -f gnatsd-v0.7.2-linux-amd64.tar.gz
  curl -JLO --silent https://github.com/nats-io/nats-server/releases/download/v0.7.2/gnatsd-v0.7.2-linux-amd64.tar.gz
  tar -xvf gnatsd-v0.7.2-linux-amd64.tar.gz
  ./gnatsd -V 2> gnatsd.stderr.log 1> gnatsd.stdout.log &
SHELL

install_blobstore_server = <<-SHELL
#!/bin/bash

  useradd vagrant || true # exists on virtualbox already
  if [ ! -e "/etc/init.d/nginx" ]; then
    apt-get -y update
    apt-get -y install nginx-full
  fi

  rm -f /etc/nginx/sites-enabled/default
  cat >/etc/nginx/nginx.conf <<EOL
#{File.read("fixtures/nginx.conf")}
EOL

  cat >/etc/nginx/sites-enabled/blobstore.conf <<EOL
#{File.read("fixtures/blobstore.conf")}
EOL

  /etc/init.d/nginx restart
SHELL

enable_ssh = <<-SHELL

# extract the zip
$OpenSSHZipPath = "C:\\bosh\\OpenSSH-Win64.zip"

Push-Location $env:PROGRAMFILES
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory($OpenSSHZipPath, $env:PROGRAMFILES)
Rename-Item .\\OpenSSH-Win64 OpenSSH

Push-Location OpenSSH
powershell -ExecutionPolicy Bypass -File install-sshd.ps1

Start-Service -Name sshd
Start-Service -Name ssh-agent

Pop-Location
Pop-Location
SHELL

# https://github.com/mitchellh/vagrant-aws/issues/566
class Hash
  def slice(*keep_keys)
    h = {}
    keep_keys.each { |key| h[key] = fetch(key) if has_key?(key) }
    h
  end unless Hash.method_defined?(:slice)
  def except(*less_keys)
    slice(*keys - less_keys)
  end unless Hash.method_defined?(:except)
end

Vagrant.configure(2) do |config|
  config.vm.provider :aws do |aws, override|
    aws.instance_type = "m4.large"
    override.vm.synced_folder ".", "/vagrant", disabled: true
  end

  config.vm.define "agent" do |agent|
    agent.vm.guest = :windows
    agent.vm.communicator = "winrm"

    agent.vm.provider :virtualbox do |v, override|
      # Private buckets:
      # https://s3.amazonaws.com/windows-bosh-private/bosh-agent.windows-integration-2012R2.box
      # https://s3.amazonaws.com/windows-bosh-private/bosh-agent.windows-integration-1709.box
      override.vm.box = "windows-integration-#{os_version}"
      v.cpus = 4
    end

    agent.vm.provider :aws do |aws, override|
      aws.ami = ami_id
      override.vm.box = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
      override.winrm.password = winrm_password
      override.winrm.username = winrm_username
      aws.instance_type = "m4.large"
      aws.access_key_id = access_key_id
      aws.secret_access_key = secret_key_id
      aws.keypair_name = keypair_name
      aws.subnet_id = subnet_id
      aws.user_data = setup_aws_winrm_user
      aws.associate_public_ip = true
      aws.block_device_mapping = [
        { 'DeviceName' => '/dev/sda1', 'Ebs.VolumeSize' => 70 },
        { 'DeviceName' => '/dev/sdb', 'Ebs.VolumeSize' => 10 },
        { 'DeviceName' => '/dev/sdc', 'Ebs.VolumeSize' => 10 }
      ]
    end

    agent.vm.provision "shell", inline: reset_bosh_directory

    `GOOS=windows go build -o fixtures/network.exe fixtures/network_windows.go`
    file_list = [
      {file: "fixtures/fixtures.tgz", dest: "c:\\bosh\\"},
      {file: "fixtures/tar.exe", dest: "c:\\bosh\\"},
      {file: "fixtures/network.exe", dest: "c:\\bosh\\"}
    ]

    file_list.each do |file_dest|
      agent.vm.provision "file", source: file_dest[:file], destination: file_dest[:dest]
    end

    provision_scripts = [
      extract_fixtures_archive,
      apply_default_agent_config,
      configure_security_settings,
      add_bosh_to_path,
      initialize_agent_service,
      put_modules_in_path,
      enable_ssh
    ]

    agent.vm.provision "shell", inline: provision_scripts.join("\n")

  end

  config.vm.define "nats" do |nats|
    nats.vm.provider :virtualbox do |v, override|
      override.vm.box = "ubuntu/trusty64"
      override.vm.provision "shell", inline: install_blobstore_server
    end

    nats.vm.provider :aws do |aws, override|
      override.vm.box = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
      aws.ami = "ami-d05e75b8"
      aws.access_key_id = access_key_id
      aws.secret_access_key = secret_key_id
      aws.keypair_name = keypair_name
      aws.subnet_id = subnet_id
      aws.user_data = install_blobstore_server
      aws.associate_public_ip = true

      override.ssh.username = "ubuntu"
      override.ssh.private_key_path = private_key_path
    end

    nats.vm.provision "shell", inline: start_nats, privileged: false
  end
end
