#!/bin/bash

# v1.0.0

# This script is designed to generate a JWT (JSON Web Token) for authenticating as a GitHub App.
# It then uses this token to perform GitHub API requests, specifically to retrieve information about a specified repository
# and display the current API rate limit status. This is particularly useful for developers and administrators
# who need to monitor their GitHub App's API usage and ensure it stays within the GitHub API rate limits.

# Inputs:
# 1. APP_ID: The unique identifier for the GitHub App. This should be passed as the first argument.
# 2. PRIVATE_KEY_PATH: The file path to the private key of the GitHub App. This should be passed as the second argument.
# 3. INSTALLATION_ID: The installation ID of the GitHub App. This should be passed as the third argument.
# 4. ORG_NAME: The name of the organization that owns the repository. This should be passed as the fourth argument.
# 5. REPO_NAME: The name of the repository to retrieve information for. This should be passed as the fifth argument.
# 6. --debug (optional): A flag that can be included to enable debug output. This can be placed anywhere in the command line.

# How to call:
# ./get-repo-info-using-github-app-and-show-api-rate-limit-info.sh [APP_ID] [PRIVATE_KEY_PATH] [INSTALLATION_ID] [ORG_NAME] [REPO_NAME]
# ./get-repo-info-using-github-app-and-show-api-rate-limit-info.sh --debug [APP_ID] [PRIVATE_KEY_PATH] [INSTALLATION_ID] [ORG_NAME] [REPO_NAME]
# ./get-repo-info-using-github-app-and-show-api-rate-limit-info.sh [APP_ID] [PRIVATE_KEY_PATH] [INSTALLATION_ID] [ORG_NAME] [REPO_NAME] --debug

# Important Notes:
# - The script requires `openssl` to generate the JWT and `curl` to make API requests.
# - The JWT generated by this script is valid for 10 minutes from its creation time.
# - Debug mode can be enabled to output detailed information about each step of the JWT creation and API request process.
# - Ensure that the private key file path is correct and the file has appropriate read permissions.
# - The script is intended for use with GitHub Apps and requires the APP_ID, PRIVATE_KEY_PATH, ORG_NAME, REPO_NAME, and INSTALLATION_ID to function correctly.

# Initialize debug mode to off
DEBUG_MODE=0

# Function to handle debug messages
debug() {
  if [ "$DEBUG_MODE" -eq 1 ]; then
    echo "DEBUG: $*"
  fi
}

# Initialize an array to hold the remaining arguments after removing recognized flags
REMAINING_ARGS=()

# Process each argument
while [ "$#" -gt 0 ]; do
  case "$1" in
    --debug)
      DEBUG_MODE=1
      shift # Remove --debug from the list of arguments
      ;;
    *)
      # Collect unrecognized arguments
      REMAINING_ARGS+=("$1")
      shift # Move to the next argument
      ;;
  esac
done

# Check if we have at least four remaining arguments for APP_ID, PRIVATE_KEY_PATH, ORG_NAME, and REPO_NAME
if [ "${#REMAINING_ARGS[@]}" -lt 4 ]; then
  echo "Usage: $0 [--debug] APP_ID PRIVATE_KEY_PATH ORG_NAME REPO_NAME"
  exit 1
fi

# Assign the remaining arguments
APP_ID="${REMAINING_ARGS[0]}"
PRIVATE_KEY_PATH="${REMAINING_ARGS[1]}"
INSTALLATION_ID="${REMAINING_ARGS[2]}"
ORG_NAME="${REMAINING_ARGS[3]}"
REPO_NAME="${REMAINING_ARGS[4]}"

# Generate JWT Header
header=$(echo -n '{"alg":"RS256","typ":"JWT"}' | openssl base64 -e -A | tr '+/' '-_' | tr -d '=')
debug "Header: $header"

# Generate JWT Payload with issued at time and expiration time
iat=$(date +%s)
debug "Issued At Time: $iat"

exp=$((iat + 600)) # JWT expiration time (10 minutes from now)
debug "Expiration Time: $exp"

payload=$(echo -n "{\"iat\":$iat,\"exp\":$exp,\"iss\":\"$APP_ID\"}" | openssl base64 -e -A | tr '+/' '-_' | tr -d '=')
debug "Payload: $payload"

# Sign the Header and Payload
signature=$(echo -n "$header.$payload" | openssl dgst -binary -sha256 -sign "$PRIVATE_KEY_PATH" | openssl base64 -e -A | tr '+/' '-_' | tr -d '=')
debug "Signature: $signature"

# Concatenate Header, Payload, and Signature to form the JWT
jwt_token="$header.$payload.$signature"
debug "JWT Token: $jwt_token"

# GitHub API URL to obtain an installation access token
access_token_url="https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens"
debug "Access Token URL: $access_token_url"

# Obtain an installation access token
response=$(curl -X POST -s -H "Authorization: Bearer ${jwt_token}" -H "Accept: application/vnd.github.v3+json" "${access_token_url}")
debug "Response: $response"

# Extract the token from the response
installation_token=$(echo "${response}" | jq -r '.token')

# Use the installation token for API calls
debug "Installation Token: ${installation_token}"

api_url="https://api.github.com/repos/$ORG_NAME/$REPO_NAME"
echo "API URL: $api_url"

# Make API Call and save response and headers
response=$(curl -i -s -H "Authorization: token ${installation_token}" -H "Accept: application/vnd.github.v3+json" "${api_url}")

# Separate headers and body
headers=$(echo "$response" | grep -Pzo '(?s)^.*?\r\n\r\n' | tr -d '\0')
body=$(echo "$response" | sed -n '/^\r$/,$p' | tail -n +2)

# Extract and echo rate limit information
echo "x-ratelimit-limit: $(echo "$headers" | grep 'x-ratelimit-limit' | awk '{print $2}')"
echo "x-ratelimit-remaining: $(echo "$headers" | grep 'x-ratelimit-remaining' | awk '{print $2}')"
echo "x-ratelimit-used: $(echo "$headers" | grep 'x-ratelimit-used' | awk '{print $2}')"
echo "x-ratelimit-reset: $(echo "$headers" | grep 'x-ratelimit-reset' | awk '{print $2}')"
echo "x-ratelimit-resource: $(echo "$headers" | grep 'x-ratelimit-resource' | awk '{print $2}')"

# Print the body of the response
echo "Repository Info: $body"