#!/bin/bash

# This script sends Deployment API information from SemaphoreCI to Jira by extracting all Jira issue keys
# from the Semaphore commit range (since last build), and sending them to Jira.
#
# It assumes GNU based bash, version 5.0.17(1)-release or later is installed running on ubuntu.
# Specifically, `grep` usage is based on a GNU based version:
# https://www.gnu.org/software/grep/manual/grep.pdf
#
# Information on the Jira Deployment API can be found at:
# https://developer.atlassian.com/cloud/jira/software/rest/api-group-deployments/#api-rest-deployments-0-1-bulk-post

echo
DEPLOYMENT_ENVIRONMENT=$1
ALLOWED_ENVIRONMENTS=("unmapped" "development" "testing" "staging" "production")
if [ -z "$DEPLOYMENT_ENVIRONMENT" ] || [[ ! " ${ALLOWED_ENVIRONMENTS[@]} " =~ " ${DEPLOYMENT_ENVIRONMENT} " ]]; then
    echo "Error: DEPLOYMENT_ENVIRONMENT is invalid. Value was set to ${DEPLOYMENT_ENVIRONMENT}."
    exit 1
fi
DEPLOYMENT_ID=$2
if [ -z "$DEPLOYMENT_ID" ]; then
    echo "Error: DEPLOYMENT_ID is empty. It needs to have a value."
    exit 1
fi

echo "DEPLOYMENT_ENVIRONMENT=${DEPLOYMENT_ENVIRONMENT}"
echo "DEPLOYMENT_ID=${DEPLOYMENT_ID}"
echo "GH_TOKEN=$(if [[ -n $GH_TOKEN ]]; then echo -n 'EXISTS'; else echo -n 'DOES_NOT_EXIST'; fi)"
echo "SEMAPHORE_GIT_REPO_SLUG=${SEMAPHORE_GIT_REPO_SLUG}"
echo "SEMAPHORE_WORKFLOW_ID=${SEMAPHORE_WORKFLOW_ID}"
echo "SEMAPHORE_WORKFLOW_NUMBER=${SEMAPHORE_WORKFLOW_NUMBER}"
echo "SEMAPHORE_PIPELINE_ID=${SEMAPHORE_PIPELINE_ID}"
echo "SEMAPHORE_GIT_COMMIT_RANGE=${SEMAPHORE_GIT_COMMIT_RANGE}"
echo "SEMAPHORE_ORGANIZATION_URL=${SEMAPHORE_ORGANIZATION_URL}"
echo "SEMAPHORE_PROJECT_NAME=${SEMAPHORE_PROJECT_NAME}"

jira_ticket_all_matches_as_lines=$(git log "$SEMAPHORE_GIT_COMMIT_RANGE" | grep -Po '\b[A-Za-z]+-\d+\b' | tr '[:lower:]' '[:upper:]')
echo "jira_ticket_all_matches_as_lines=$jira_ticket_all_matches_as_lines"

# Remove duplicate issue key ids & put into a space delimited list of keys
JIRA_TICKETS=$(echo $(printf %s "$jira_ticket_all_matches_as_lines" | sort -u))
echo "JIRA_TICKETS=${JIRA_TICKETS}"

if [[ -n "${JIRA_TICKETS}" ]]; then
    echo "Authenticating with Jira to retrieve access token..."
    authTokenResponse=$(curl -s -L --request POST https://api.atlassian.com/oauth/token \
        -H "Content-Type: application/json" \
        --data-raw "{
        \"audience\": \"api.atlassian.com\",
        \"grant_type\": \"client_credentials\",
        \"client_id\": \"${JIRA_CLIENT_ID}\",
        \"client_secret\": \"${JIRA_CLIENT_SECRET}\"
    }")

    accessToken=$(echo $authTokenResponse | jq -r '.access_token')
    if [[ "$accessToken" == "null" ]]; then
        echo "Failed to retrieve access token from jira: ${authTokenResponse}"
        echo "Exiting"
        exit 1
    fi

    echo "Jira authentication token retrieved."

    echo "Packaging deployment information into api request..."
    msSinceEpoch=$(date +%s | cut -b1-13)
    lastUpdated=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    semaphoreWorkflowUrl="${SEMAPHORE_ORGANIZATION_URL}/workflows/${SEMAPHORE_WORKFLOW_ID}"
    semaphorePipelineUrl="${semaphoreWorkflowUrl}?pipeline_id=${SEMAPHORE_PIPELINE_ID}"

    JIRA_TICKETS_AS_COMMA_DELIMITED_LIST=$(echo $JIRA_TICKETS | sed 's| |", "|g;s|.*|"&"|')
    deploymentData="{
    \"deployments\": [
            {
            \"deploymentSequenceNumber\": \"${SEMAPHORE_WORKFLOW_NUMBER}\",
            \"updateSequenceNumber\": \"${msSinceEpoch}\",
            \"associations\": [ {
                    \"associationType\": \"issueIdOrKeys\",
                    \"values\": [${JIRA_TICKETS_AS_COMMA_DELIMITED_LIST}]
                } ],
            \"displayName\": \"${SEMAPHORE_PROJECT_NAME}-${SEMAPHORE_WORKFLOW_NUMBER}\",
            \"url\": \"${semaphorePipelineUrl}\",
            \"description\": \"Deploying ${SEMAPHORE_PROJECT_NAME}-${SEMAPHORE_WORKFLOW_NUMBER}\",
            \"lastUpdated\": \"${lastUpdated}\",
            \"state\": \"successful\",
            \"pipeline\": {
                \"id\": \"${SEMAPHORE_PROJECT_NAME}-deployment-to-${DEPLOYMENT_ENVIRONMENT}\",
                \"displayName\": \"${SEMAPHORE_PROJECT_NAME}-deployment-to-${DEPLOYMENT_ENVIRONMENT}\",
                \"url\": \"${semaphoreWorkflowUrl}\"
            },
            \"environment\": {
                \"id\": \"${DEPLOYMENT_ID}\",
                \"displayName\": \"${DEPLOYMENT_ID}\",
                \"type\": \"${DEPLOYMENT_ENVIRONMENT}\"
            }
            }
        ]
    }"

    cloudId="02a6be27-7c36-424d-b25c-2c2915398b66" #https://mediafly.atlassian.net/_edge/tenant_info
    deploymentsUrl="https://api.atlassian.com/jira/deployments/0.1/cloud/${cloudId}/bulk"

    echo "${deploymentsUrl}"
    echo "${deploymentData}"

    echo "Sending deployment information to Jira:"
    deployResponse=$(curl -s -L --request POST $deploymentsUrl \
        -H "Authorization: Bearer ${accessToken}" \
        -H "Content-Type: application/json" \
        --data-raw "${deploymentData}")

    echo "Jira Deployments API response: ${deployResponse}"
else
    echo "No Jira tickets found for this changeset: JIRA_TICKETS=${JIRA_TICKETS}"
fi
echo
