#!/usr/bin/env bash
#===============================================================================
# cmz-auth.sh
#
# Retrieves a scoped bearer token from the Cloudamize PreCloud API. Exchanges
# Basic-auth credentials for an access token and — when the account spans
# multiple engagements — prompts for a customer ID and returns a
# customer-scoped token. When the account has a single engagement, the
# customer ID is looked up automatically from /engagements.
#
# Copyright (c) 2026 Cloudamize. All rights reserved.
# Proprietary and confidential. Internal use only — do not distribute.
#
# Product    : Cloudamize — Cloud Migration, Analytics & FinOps Platform
# Component  : PreCloud API / Authentication
# Maintainer : Platform Engineering <platform@cloudamize.com>
# Version    : 1.1.0
# Updated    : 2026-09-11
#
# Usage:
#   API_USER='<email>' API_PASS='<password>' ./cmz-auth.sh
#   TOKEN=$(API_USER='<email>' API_PASS='<password>' ./cmz-auth.sh)
#
#   Credentials are read from the environment — never hardcode them here.
#
# Requirements : bash 4+, curl 7.76+ (--fail-with-body), jq 1.6+
#
# Exit codes:
#   0  success — token written to stdout
#   1  missing credentials, auth failure, or malformed API response
#===============================================================================
set -euo pipefail
API_BASE="https://precloud-api.cloudamize.com"
CLOUDAMIZE_USER="${API_USER:-your-email@email.com}"
CLOUDAMIZE_PASS="${API_PASS:-your password}"
CURL=(curl --fail-with-body --silent --show-error --location
      --connect-timeout 5 --max-time 30)
log() { printf '%s\n' "$*" >&2; }
die() { log "ERROR: $*"; exit 1; }
api_get() {  # url token
  "${CURL[@]}" "$1" -H "Authorization: Bearer $2"
}
log "Requesting initial token..."
auth_json=$("${CURL[@]}" --user "$CLOUDAMIZE_USER:$CLOUDAMIZE_PASS" \
            "$API_BASE/auth/token?termsAccepted=true") \
  || die "auth/token failed"
token=$(jq -er '.access_token' <<<"$auth_json") \
  || die "no access_token: $auth_json"
log "Initial token received."
user_json=$(api_get "$API_BASE/user/data" "$token") \
  || die "user/data failed"
has_multi=$(jq -r '(.hasMultipleEngagements // false)' <<<"$user_json")
if [[ "$has_multi" == "true" ]]; then
  log "Multiple engagements found."
  eng_json=$(api_get "$API_BASE/engagements" "$token") \
    || die "engagements failed"
  # tolerate bare array or {engagements:[...]}
  jq -r '(if type=="array" then . else .engagements end)[]
         | "\(.customerId)\t\(.company // .customerName // .name)"' \
    <<<"$eng_json" | column -t -s $'\t' >&2
  read -rp "Enter Customer ID: " customer_id
  [[ -n "$customer_id" ]] || die "no customer ID entered"
  final_json=$(api_get "$API_BASE/auth/token?customerId=${customer_id}" "$token") \
    || die "customer token failed"
  final_token=$(jq -er '.access_token' <<<"$final_json") \
    || die "no access_token for $customer_id: $final_json"
else
  log "Single engagement found."
  eng_json=$(api_get "$API_BASE/engagements" "$token") \
    || die "engagements failed"
  # tolerate bare array or {engagements:[...]}; single engagement so take the first entry
  customer_id=$(jq -er '(if type=="array" then . else .engagements end)[0].customerId' \
                <<<"$eng_json") \
    || die "no customerId in engagements response: $eng_json"
  log "Resolved customer ID: $customer_id"
  final_json=$(api_get "$API_BASE/auth/token?customerId=${customer_id}" "$token") \
    || die "customer token failed"
  final_token=$(jq -er '.access_token' <<<"$final_json") \
    || die "no access_token for $customer_id: $final_json"
fi
printf '%s\n' "$final_token"
