#!/usr/bin/env sh
# @file ansible-gen-readme-collection
# @description
#
# This script generates a README.md file for an Ansible collection. Content is fetched
# from the information in `galaxy.yml`, the individual roles in
# `roles/*/README.md`, and the playbooks in `playbooks/*`.
#
# By default, the current working directory is used as the source. Via parameters, a
# different directory can be specified.
#
# The role table uses the content between the title and `## Table of contents` in each
# role README. The playbook table uses the name of the first play in each playbook.
#

set -eu

COLLECTION_DIR="$(readlink -f "${@:-.}")"

if [ ! -f "${COLLECTION_DIR}"/galaxy.yml ]; then
  echo "script must be executed from main collection directory"
  exit 1
fi

COLLECTION_NAME="$(yq eval '.namespace' "${COLLECTION_DIR}"/galaxy.yml).$(yq eval '.name' "${COLLECTION_DIR}"/galaxy.yml)"
COLLECTION_TITLE="Ansible collection '${COLLECTION_NAME}'"
echo "Generate README.md for ${COLLECTION_TITLE}"
COLLECTION_DESCRIPTION="$(yq eval '.description' "${COLLECTION_DIR}"/galaxy.yml)"
COLLECTION_DEPENDENCIES="$(yq eval '.dependencies | ... comments=""' "${COLLECTION_DIR}"/galaxy.yml | sed "s/{}/None./g; s/^/- /g")"
COLLECTION_LICENSE="$(yq eval '.license' "${COLLECTION_DIR}"/galaxy.yml)"
COLLECTION_AUTHORS="$(yq eval '.authors[]' "${COLLECTION_DIR}"/galaxy.yml | sed "s/^/- /g")"

read_role_intro() {
  awk '
    NR == 1 { next }
    /^## Table of contents$/ { exit }
    {
      if ($0 == "") {
        if (content != "" && !blank) {
          content = content "<br><br>"
          blank = 1
        }
        next
      }
      if (content != "" && !blank) {
        content = content " "
      }
      content = content $0
      blank = 0
    }
    END {
      sub(/(<br><br>)+$/, "", content)
      print content
    }
  ' "$1" | sed 's/|/\\|/g'
}

COLLECTION_ROLES_TABLE="| Role | Overview |
"
COLLECTION_ROLES_TABLE="${COLLECTION_ROLES_TABLE}| --- | --- |
"
for i in "${COLLECTION_DIR}"/roles/*; do
  ROLE_NAME="[${COLLECTION_NAME}.$(basename "${i}")](roles/$(basename "${i}")/README.md)"
  ROLE_DESCRIPTION="$(read_role_intro "${i}"/README.md)"
  COLLECTION_ROLES_TABLE="${COLLECTION_ROLES_TABLE}| ${ROLE_NAME} | ${ROLE_DESCRIPTION} |
"
done

COLLECTION_PLAYBOOKS_TABLE=""
for i in "${COLLECTION_DIR}"/playbooks/*.yml "${COLLECTION_DIR}"/playbooks/*.yaml; do
  [ -f "${i}" ] || continue
  PLAYBOOK_FILE="$(basename "${i}")"
  PLAYBOOK_NAME="[${COLLECTION_NAME}.${PLAYBOOK_FILE%.*}](playbooks/${PLAYBOOK_FILE})"
  PLAYBOOK_DESCRIPTION="$(yq eval '.[0].name' "${i}" | sed 's/|/\\|/g')"
  if [ -z "${COLLECTION_PLAYBOOKS_TABLE}" ]; then
    COLLECTION_PLAYBOOKS_TABLE="| Playbook | Overview |
| --- | --- |
"
  fi
  COLLECTION_PLAYBOOKS_TABLE="${COLLECTION_PLAYBOOKS_TABLE}| ${PLAYBOOK_NAME} | ${PLAYBOOK_DESCRIPTION} |
"
done

COLLECTION_PLAYBOOKS_SECTION=""
if [ -n "${COLLECTION_PLAYBOOKS_TABLE}" ]; then
  COLLECTION_PLAYBOOKS_SECTION="## Playbooks

${COLLECTION_PLAYBOOKS_TABLE}
"
fi

cat <<EOF > "${COLLECTION_DIR}"/README.md
<!-- Generated by ansible-gen-readme-collection. Update galaxy.yml, role READMEs, or playbooks instead. -->

# ${COLLECTION_TITLE}

${COLLECTION_DESCRIPTION}

## Roles

${COLLECTION_ROLES_TABLE}
${COLLECTION_PLAYBOOKS_SECTION}## Dependencies

${COLLECTION_DEPENDENCIES}

## License

${COLLECTION_LICENSE}

## Authors

${COLLECTION_AUTHORS}
EOF
