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

TARGET_ROOT="${1:-.}"
BLACKSHIELD_API_URL="${BLACKSHIELD_API_URL:-https://api.blackshield.chaplau.com}"
BLACKSHIELD_API_KEY="${BLACKSHIELD_API_KEY:-}"
BLACKSHIELD_PIPELINE_IMAGE="${BLACKSHIELD_PIPELINE_IMAGE:-public.ecr.aws/blackshield-security/pipeline-scanner:1.0.9}"
BLACKSHIELD_PIPELINE_TOOLS="${BLACKSHIELD_PIPELINE_TOOLS:-trivy,trufflehog,syft}"
BLACKSHIELD_REPO_CHANGE_MODE="${BLACKSHIELD_REPO_CHANGE_MODE:-create_branch_commit}"
BLACKSHIELD_BRANCH_NAME="${BLACKSHIELD_BRANCH_NAME:-blackshield/security-scan}"

fail() {
  printf 'Error: %s\n' "$1" >&2
  exit 1
}

require_command() {
  command -v "$1" >/dev/null 2>&1 || fail "Install $1 before running this installer."
}

detect_repo_slug() {
  if [ -n "${BITBUCKET_REPO_SLUG:-}" ]; then
    printf '%s' "$BITBUCKET_REPO_SLUG"
    return
  fi
  local remote_url
  remote_url="$(git -C "$TARGET_ROOT" config --get remote.origin.url 2>/dev/null || true)"
  remote_url="${remote_url%.git}"
  case "$remote_url" in
    https://bitbucket.org/*/*)
      printf '%s' "${remote_url##*/}"
      ;;
    git@bitbucket.org:*/*)
      printf '%s' "${remote_url##*/}"
      ;;
    *)
      fail "Set BITBUCKET_REPO_SLUG or run this from a Bitbucket repository checkout."
      ;;
  esac
}

detect_workspace() {
  if [ -n "${BITBUCKET_WORKSPACE:-}" ]; then
    printf '%s' "$BITBUCKET_WORKSPACE"
    return
  fi
  local remote_url without_suffix
  remote_url="$(git -C "$TARGET_ROOT" config --get remote.origin.url 2>/dev/null || true)"
  without_suffix="${remote_url%.git}"
  case "$without_suffix" in
    https://bitbucket.org/*/*)
      without_suffix="${without_suffix#https://bitbucket.org/}"
      printf '%s' "${without_suffix%%/*}"
      ;;
    git@bitbucket.org:*/*)
      without_suffix="${without_suffix#git@bitbucket.org:}"
      printf '%s' "${without_suffix%%/*}"
      ;;
    *)
      fail "Set BITBUCKET_WORKSPACE or run this from a Bitbucket repository checkout."
      ;;
  esac
}

set_bitbucket_variable() {
  local key="$1"
  local value="$2"
  local secured="$3"
  local existing_uuid payload endpoint
  endpoint="https://api.bitbucket.org/2.0/repositories/${workspace}/${repo_slug}/pipelines_config/variables"
  existing_uuid="$(
    curl -fsS -u "${BITBUCKET_USERNAME}:${BITBUCKET_APP_PASSWORD}" "$endpoint" |
      python3 -c 'import json,sys; data=json.load(sys.stdin); key=sys.argv[1]; print(next((item["uuid"] for item in data.get("values", []) if item.get("key") == key), ""))' "$key"
  )"
  payload="$(
    python3 -c 'import json,sys; print(json.dumps({"key": sys.argv[1], "value": sys.argv[2], "secured": sys.argv[3] == "true"}))' "$key" "$value" "$secured"
  )"
  if [ -n "$existing_uuid" ]; then
    curl -fsS -u "${BITBUCKET_USERNAME}:${BITBUCKET_APP_PASSWORD}" \
      -H "Content-Type: application/json" \
      -X PUT \
      -d "$payload" \
      "$endpoint/${existing_uuid}" >/dev/null
  else
    curl -fsS -u "${BITBUCKET_USERNAME}:${BITBUCKET_APP_PASSWORD}" \
      -H "Content-Type: application/json" \
      -X POST \
      -d "$payload" \
      "$endpoint" >/dev/null
  fi
}

format_tool_steps() {
  local IFS=',' tool
  read -ra tools <<< "$BLACKSHIELD_PIPELINE_TOOLS"
  for tool in "${tools[@]}"; do
    tool="${tool// /}"
    [ -n "$tool" ] || continue
    cat <<EOF
        - step:
            name: BlackShield ${tool}
            image: ${BLACKSHIELD_PIPELINE_IMAGE}
            script:
              - export SCAN_TOOL="${tool}"
              - export SCAN_TARGET="\${BITBUCKET_CLONE_DIR}"
              - export REPOSITORY_NAME="\${BITBUCKET_REPO_FULL_NAME}"
              - export SCAN_INTERVAL_SECONDS="0"
              - export LOG_LEVEL="INFO"
              - python -m pipeline.entrypoint
            services:
              - docker
EOF
  done
}

[ -n "$BLACKSHIELD_API_KEY" ] || fail "BLACKSHIELD_API_KEY is required; rerun the dashboard wizard to generate a scoped key."
require_command curl
require_command git
require_command python3
[ -n "${BITBUCKET_USERNAME:-}" ] || fail "Set BITBUCKET_USERNAME to your Bitbucket username."
[ -n "${BITBUCKET_APP_PASSWORD:-}" ] || fail "Set BITBUCKET_APP_PASSWORD to an app password with repository admin and pipeline variable access."

workspace="$(detect_workspace)"
repo_slug="$(detect_repo_slug)"

curl -fsS -u "${BITBUCKET_USERNAME}:${BITBUCKET_APP_PASSWORD}" \
  "https://api.bitbucket.org/2.0/repositories/${workspace}/${repo_slug}" >/dev/null ||
  fail "Bitbucket authentication failed. Create an app password, export BITBUCKET_USERNAME and BITBUCKET_APP_PASSWORD, then rerun."

set_bitbucket_variable "BLACKSHIELD_API_KEY" "$BLACKSHIELD_API_KEY" "true"
set_bitbucket_variable "BLACKSHIELD_API_URL" "$BLACKSHIELD_API_URL" "false"

cat > "$TARGET_ROOT/bitbucket-pipelines.yml" <<EOF
image: atlassian/default-image:4

pipelines:
  pull-requests:
    "**":
      - parallel:
$(format_tool_steps)
  branches:
    main:
      - parallel:
$(format_tool_steps)

definitions:
  services:
    docker:
      memory: 2048
EOF

printf "Configured Bitbucket repository variables for %s/%s.\n" "$workspace" "$repo_slug"
printf "Wrote source bundle files:\n"
printf "  - %s\n" "$TARGET_ROOT/bitbucket-pipelines.yml"

if [ "$BLACKSHIELD_REPO_CHANGE_MODE" = "create_branch_commit" ]; then
  git -C "$TARGET_ROOT" checkout -B "$BLACKSHIELD_BRANCH_NAME"
  git -C "$TARGET_ROOT" add bitbucket-pipelines.yml
  git -C "$TARGET_ROOT" commit -m "chore: add BlackShield security scan" || true
  git -C "$TARGET_ROOT" push -u origin "$BLACKSHIELD_BRANCH_NAME"
  printf "Pushed %s. Open a pull request in Bitbucket if one was not created automatically.\n" "$BLACKSHIELD_BRANCH_NAME"
fi
