#!/usr/bin/env bash
set -euo pipefail

SIGNALGRID_CLIENT_KEY="your_client_key_here"
SIGNALGRID_CHANNEL="your_channel_token_here"

WARNING_DAYS=30
CRITICAL_DAYS=7

TARGETS=(
  "example.com:443"
  "api.example.com:443"
)

push_notification() {
  local type="$1"
  local critical="$2"
  local title="$3"
  local body="$4"

  curl --silent --show-error --fail -X POST https://api.signalgrid.co/v1/push \
    --data-urlencode "client_key=${SIGNALGRID_CLIENT_KEY}" \
    --data-urlencode "channel=${SIGNALGRID_CHANNEL}" \
    --data-urlencode "type=${type}" \
    --data-urlencode "critical=${critical}" \
    --data-urlencode "title=${title}" \
    --data-urlencode "body=${body}" >/dev/null
}

check_target() {
  local target="$1"
  local host="${target%%:*}"
  local port="${target##*:}"
  local end_date
  local end_epoch
  local now_epoch
  local seconds_left
  local days_left

  end_date="$({
    echo | openssl s_client -servername "$host" -connect "$host:$port" 2>/dev/null \
      | openssl x509 -noout -enddate \
      | cut -d= -f2
  } || true)"

  if [ -z "$end_date" ]; then
    push_notification \
      "CRIT" \
      "true" \
      "Certificate check failed: ${host}" \
      "Could not read the TLS certificate from ${host}:${port}."
    return
  fi

  end_epoch="$(date -d "$end_date" +%s)"
  now_epoch="$(date +%s)"
  seconds_left=$((end_epoch - now_epoch))
  days_left=$(((seconds_left + 86399) / 86400))

  if [ "$seconds_left" -le 0 ]; then
    push_notification \
      "CRIT" \
      "true" \
      "Certificate expired: ${host}" \
      "${host}:${port} expired on ${end_date}."
    return
  fi

  if [ "$days_left" -le "$CRITICAL_DAYS" ]; then
    push_notification \
      "CRIT" \
      "true" \
      "Certificate expires soon: ${host}" \
      "${host}:${port} expires in ${days_left} day(s) on ${end_date}."
  elif [ "$days_left" -le "$WARNING_DAYS" ]; then
    push_notification \
      "WARN" \
      "false" \
      "Certificate expiration warning: ${host}" \
      "${host}:${port} expires in ${days_left} day(s) on ${end_date}."
  fi
}

for target in "${TARGETS[@]}"; do
  check_target "$target"
done
