#!/bin/bash
# ==============================================================================
# GUARDiA ITSM — SSL 인증서 만료일 점검 스크립트
# 경로: /opt/guardia/scripts/ssl/ssl_expiry_check.sh
#
# 사용법:
#   ./ssl_expiry_check.sh <호스트> [포트(기본 443)] [timeout(기본 5초)]
#
# 출력 (JSON):
#   성공: {"host":"...","port":443,"expiry":"...","days_left":N,"level":"OK|WARN|CRITICAL","issuer":"..."}
#   실패: {"host":"...","port":443,"status":"ERROR","message":"..."}
#
# 반환 코드:
#   0 — 점검 완료 (OK/WARN/CRITICAL 모두)
#   1 — 인증서 조회 실패
# ==============================================================================

HOST="${1}"
PORT="${2:-443}"
TIMEOUT="${3:-5}"

if [ -z "${HOST}" ]; then
    echo '{"status":"ERROR","message":"호스트 인수가 필요합니다. 사용법: ssl_expiry_check.sh <host> [port]"}'
    exit 1
fi

# openssl 설치 확인
if ! command -v openssl &>/dev/null; then
    echo '{"status":"ERROR","message":"openssl 명령어를 찾을 수 없습니다."}'
    exit 1
fi

# ── 인증서 정보 조회 ──────────────────────────────────────────────────────────
CERT_INFO=$(echo | timeout "${TIMEOUT}" openssl s_client \
    -servername "${HOST}" \
    -connect "${HOST}:${PORT}" \
    2>/dev/null)

if [ -z "${CERT_INFO}" ]; then
    echo "{\"host\":\"${HOST}\",\"port\":${PORT},\"status\":\"ERROR\",\"message\":\"연결 실패 또는 타임아웃 (${TIMEOUT}s)\"}"
    exit 1
fi

# 만료일 추출
EXPIRY=$(echo "${CERT_INFO}" | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -z "${EXPIRY}" ]; then
    echo "{\"host\":\"${HOST}\",\"port\":${PORT},\"status\":\"ERROR\",\"message\":\"인증서 만료일을 파싱할 수 없습니다.\"}"
    exit 1
fi

# 발급기관 추출
ISSUER=$(echo "${CERT_INFO}" | openssl x509 -noout -issuer 2>/dev/null \
    | sed 's/^issuer=//' | tr -d '\n' | sed 's/"/\\"/g')

# 주체(CN) 추출
SUBJECT_CN=$(echo "${CERT_INFO}" | openssl x509 -noout -subject 2>/dev/null \
    | grep -oP '(?<=CN = )[^,]+' | head -1 | tr -d '\n' | sed 's/"/\\"/g')

# ── 날짜 계산 ─────────────────────────────────────────────────────────────────
# Linux date 와 macOS date 모두 지원
EXPIRY_TS=$(date -d "${EXPIRY}" +%s 2>/dev/null)
if [ -z "${EXPIRY_TS}" ]; then
    # macOS/BSD 형식 시도
    EXPIRY_TS=$(date -jf "%b %d %T %Y %Z" "${EXPIRY}" +%s 2>/dev/null)
fi
if [ -z "${EXPIRY_TS}" ]; then
    # 추가 형식 시도 (Jan  1 ...)
    EXPIRY_TS=$(date -d "$(echo "${EXPIRY}" | tr -s ' ')" +%s 2>/dev/null)
fi

if [ -z "${EXPIRY_TS}" ]; then
    echo "{\"host\":\"${HOST}\",\"port\":${PORT},\"expiry\":\"${EXPIRY}\",\"status\":\"ERROR\",\"message\":\"날짜 파싱 실패\"}"
    exit 1
fi

NOW_TS=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_TS - NOW_TS) / 86400 ))

# ── 알림 등급 ─────────────────────────────────────────────────────────────────
LEVEL="OK"
if [ "${DAYS_LEFT}" -le 0 ]; then
    LEVEL="EXPIRED"
elif [ "${DAYS_LEFT}" -le 7 ]; then
    LEVEL="CRITICAL"
elif [ "${DAYS_LEFT}" -le 30 ]; then
    LEVEL="WARN"
fi

# ── JSON 출력 ─────────────────────────────────────────────────────────────────
cat <<EOF
{"host":"${HOST}","port":${PORT},"expiry":"${EXPIRY}","days_left":${DAYS_LEFT},"level":"${LEVEL}","issuer":"${ISSUER}","subject_cn":"${SUBJECT_CN}"}
EOF

exit 0
