#!/opt/chef/embedded/bin/ruby
# For ChecCI integration tests we should hide secure data
# which could affect our existing environment (e.g. database credentials),
# but keep recipes working.
#
# This script will replace value of all data bag items with phrase 'secure data',
# if key name of this item exists in exclude file.

require 'chef/encrypted_data_bag_item'
require 'chef/encrypted_data_bag_item/check_encrypted'

# Because we already have secret file path and Chef repo path in ci.sh script,
# we'll pass it as parameters to the script

if !ARGV.empty? && ARGV.length == 2
  secret_file = ARGV[0]
  chef_repo_path = ARGV[1]
else
  puts 'You did not provide required arguments',
       '1 - secret file path for chef data bags',
       '2 - path to data bag files'
  exit false
end

class Decryptor
  # This module decrypts data bag items
  # It uses built in Chef functionality

  def initialize(secret_file)
    @secret = Chef::EncryptedDataBagItem.load_secret(secret_file)
  end

  def decrypt_item(item)
    # item - path to the data bag item file

    encrypted_data = JSON.parse(File.read(item))
    check_encryption = Class.new.extend(Chef::EncryptedDataBagItem::CheckEncrypted)
    decrypted_data = if check_encryption.encrypted?(encrypted_data)
                       Chef::EncryptedDataBagItem.new(encrypted_data, @secret)
                     else
                       encrypted_data
                     end

    decrypted_data.to_hash
  end
end

data_bags_path = "#{chef_repo_path}/data_bags/secrets/"
exclude_file = "#{Dir.home}/irrigate-chef-ci/scripts/.secure_keys"

decryptor = Decryptor.new(secret_file)

Dir.glob("#{data_bags_path}*.json").each do |file|
  file_data = decryptor.decrypt_item(file)
  if File.exist?(exclude_file)
    exclude_keys = File.readlines(exclude_file).map(&:chomp)

    keys = file_data.keys
    next if keys.include?('test_safety') && file_data['test_safety']
    exclude_keys.each do |key|
      file_data[key] = 'secure_data' if keys.include?(key)
    end
  end
  File.open(file, 'w') do |f|
    f.write(JSON.pretty_generate(file_data))
  end
end
