#!/usr/bin/env bash
#
# This script automaticaly generates .kitchen.yml file for testing
# and resolves all dependensies

CHEF_REPO_PATH='chef_repo'
ROLES_PATH="${CHEF_REPO_PATH}/roles"
SECRET_KEY_PATH='/etc/chef/encrypted_data_bag_secret'

GITHUB_ORG='theorchard'
CHEF_REPO="git@github.com:${GITHUB_ORG}/irrigate-chef-repo.git"

ROLES=()
RECIPES=()

# ${WORKSPACE} should be set by jenkins as environment variable
cd ${WORKSPACE}

# For using roles and data bags in our tests, we have to clone irrigate-chef-repo
rm -rf ${CHEF_REPO_PATH}
git clone ${CHEF_REPO} ${CHEF_REPO_PATH}

# We have recipes which shouldn't be used anywhere except production
while IFS='' read -r recipe || [[ -n "$line" ]]; do
    sed -i "/$recipe/d" ${CHEF_REPO_PATH}/roles/*.json
done < $(dirname $0)/ignore_recipes

# Determine which recipes were changed (could be list)
# recipe files in PR
REPO_NAME="$(basename -s .git "$(git config --get remote.origin.url)")"
COOKBOOK="$(grep name metadata.rb | egrep -o 'irrigate-\w+')"

# If recipe or test for that recipe was changed, we'll test it 
CHANGED_RECIPES="$(basename -s .rb "$(git diff --name-only origin/master | grep -e 'recipes' -e 'test/smoke' || echo 'false')")"

if [[ "${CHANGED_RECIPES}" == "false" ]]; then
  echo "No recipes were changed, exiting..."
  exit 0
fi

# Perform decryption of secret data bag items
# and overwriting secure values

$(dirname $0)/decryptor.rb "${SECRET_KEY_PATH}" "${CHEF_REPO_PATH}"

for file in ${CHANGED_RECIPES}; do
  for role in $(grep "recipe\[${COOKBOOK}::${file}" -lir ${ROLES_PATH}); do
    role_file="$(basename ${role})"
    role_name=${role_file%%.*}
    ROLES+=(${role_name})
    for recipe in $(egrep -h 'recipe\[irrigate' ${ROLES_PATH}/${role_file} | egrep -o 'irrigate-\w+::\w+'); do
      RECIPES+=(${recipe})
    done
  done
done

COOKBOOKS=($(echo ${RECIPES[@]} | egrep -o 'irrigate-\w+' | sort | uniq))

# Because we use chef-zero in kitchen we should download all cookbooks used in role
mkdir cookbooks
pushd cookbooks
for cookbook in ${COOKBOOKS[@]}; do
  if [[ "${cookbook}" != "${COOKBOOK}" ]]; then
    git clone git@github.com:${GITHUB_ORG}/${cookbook}.git

    # Adding dependencies in Berksfile as local cookbooks (required for kitchen)
    grep "cookbook '${cookbook}', path: 'cookbooks/${cookbook}'" ../Berksfile || \
    echo "cookbook '${cookbook}', path: 'cookbooks/${cookbook}'" >> ../Berksfile

    # Modify related paths for File.read() methods
    grep -r -l 'File.read' ${cookbook}/test/smoke/ | xargs sed -i "s;File.read(';File.read('cookbooks/${cookbook}/;g"
    grep -r -l 'File.read' ${cookbook}/test/smoke/ | xargs sed -i "s;File.read(\";File.read(\"cookbooks/${cookbook}/;g"
  fi
done
echo "cookbook 'irrigate-chef-ci', path: '~/irrigate-chef-ci/cookbook'" >> ../Berksfile
popd

# Generating .kitchen.yml file
cat > .kitchen.yml << EOF
driver:
  name: docker

provisioner:
  name: chef_zero
  always_update_cookbooks: true
  product_name: chef
  product_version: 12
verifier:
  name: inspec

transport:
  username: 'kitchen'
  password: 'kitchen'

platforms:
  - name: centos-7.3
    driver_config:
      dockerfile: ~/irrigate-chef-ci/kitchen/Dockerfile
      privileged: true # Needed by systemd to access cgroups
      run_command: /usr/sbin/init # Start systemd as root process
      use_sudo: false
      build_options: --build-arg chef_ci_image=${chef_ci_image}
    attributes:
      chefci_testing: true
      authorization:
        sudo:
          users:
            - 'kitchen'

EOF

if [[ -n "${ROLES[@]}" ]]; then
  echo "suites:" >> .kitchen.yml
fi

for role in ${ROLES[@]}; do
  recipes_in_role="$(egrep -h 'recipe\[irrigate' ${ROLES_PATH}/${role}.json | egrep -o 'irrigate-\w+::\w+')"
  cat >> .kitchen.yml << EOF
    - name: ${role}
      data_bags_path: "${CHEF_REPO_PATH}/data_bags"
      roles_path: "${CHEF_REPO_PATH}/roles"
      run_list:
        - role[${role}]
        - recipe[irrigate-chef-ci]
      verifier:
        inspec_tests:
EOF
  for recipe in ${recipes_in_role}; do
    test_file="cookbooks/${recipe%::*}/test/smoke/${recipe##*::}"
    if [[ "${recipe%::*}" == "${COOKBOOK}" ]]; then
      test_file="test/smoke/${recipe##*::}"
    fi
    if [[ -d ${test_file} ]]; then
      cat >> .kitchen.yml << EOF
          - ${test_file}
EOF
    elif [[ -f "${test_file}.rb" ]]; then
      cat >> .kitchen.yml << EOF
          - ${test_file}.rb
EOF
    else
      echo "${test_file} does not exist"
    fi
  done
done

echo "time to fire kitchen test"

# Performing integration tests
kitchen test --destroy always
