#!/usr/bin/env bash

# Flows
source ./flows/base
source ./flows/git
source ./flows/kube
source ./flows/packaging
source ./flows/rust

# Vars
POSTGRES_VERSION="18"
POSTGRES_CONFIG_PATH="/opt/homebrew/opt/postgresql@${POSTGRES_VERSION}/bin/pg_config"
DEPENDENCIES+=(icu4c pkg-config "postgresql@${POSTGRES_VERSION}")
CARGO_DEPENDENCIES=(cargo-pgrx==0.16.1)
GITEA_ORGANIZATION="cellular"
GITEA_REPOSITORY="jspg"

pgrx-up() {
  info "Initializing pgrx..."
  # Explicitly point to the postgresql@${POSTGRES_VERSION} pg_config, don't rely on 'which'
  local POSTGRES_CONFIG_PATH="/opt/homebrew/opt/postgresql@${POSTGRES_VERSION}/bin/pg_config"

  if [ ! -x "$POSTGRES_CONFIG_PATH" ]; then
    warning "Ensure postgresql@${POSTGRES_VERSION} is installed correctly via Homebrew."
    abort "pg_config not found or not executable at $POSTGRES_CONFIG_PATH." 2
  fi

  if cargo pgrx init --pg"$POSTGRES_VERSION"="$POSTGRES_CONFIG_PATH"; then
    success "pgrx initialized successfully." && return 0
  fi

  abort "Failed to initialize pgrx. Check PostgreSQL development packages are installed and $POSTGRES_CONFIG_PATH is valid." 2
}

pgrx-down() {
  info "Taking pgrx down..."
}


build() {
  local version
  version=$(get-version) || return $?
  local package_dir="./package"
  local tarball_name="${GITEA_REPOSITORY}.tar.gz"
  local tarball_path="${package_dir}/${tarball_name}"

  info "Creating source tarball v$version for ${GITEA_REPOSITORY} in $package_dir..."
  
  # Clean previous package dir
  rm -rf "${package_dir}"
  mkdir -p "${package_dir}"

  # Create the source tarball excluding specified patterns
  info "Creating tarball: ${tarball_path}"
  # Set COPYFILE_DISABLE=1 to prevent macOS tar from including ._ metadata files
  if COPYFILE_DISABLE=1 tar --exclude='.git*' --exclude='./target' --exclude='./package' --exclude='./flows' --exclude='./flow' -czf "${tarball_path}" .; then
    success "Successfully created source tarball: ${tarball_path}" && return 0
  fi
  
  abort "Failed to create source tarball." 2
}

install() {
  local version
  version=$(get-version) || return $? # Propagate error

  info "Building and installing PGRX extension v$version into local PostgreSQL..."

  # Run the pgrx install command
  if ! cargo pgrx install; then 
      abort "cargo pgrx install command failed." 2
  fi
  success "PGRX extension v$version successfully built and installed."

  # Post-install modification to allow non-superuser usage
  local pg_sharedir
  pg_sharedir=$("$POSTGRES_CONFIG_PATH" --sharedir)
  local pg_config_status=$?
  if [ $pg_config_status -ne 0 ] || [ -z "$pg_sharedir" ]; then
      abort "Failed to determine PostgreSQL shared directory using pg_config." 2
  fi
  local installed_control_path="${pg_sharedir}/extension/jspg.control"

  # Modify the control file
  if [ ! -f "$installed_control_path" ]; then
    abort "Installed control file not found: '$installed_control_path'" 2
  fi

  info "Modifying control file for non-superuser access: ${installed_control_path}"
  # Use sed -i '' for macOS compatibility
  if sed -i '' '/^superuser = false/d' "$installed_control_path" && \
     echo 'trusted = true' >> "$installed_control_path"; then
    success "Control file modified successfully." && return 0
  fi

  abort "Failed to modify control file: ${installed_control_path}" 2
}

test() {
  info "Running jspg tests..."
  cargo test --tests "$@" || return $?
}

clean() {
  info "Cleaning build artifacts..."
  cargo clean || return $?
}

jspg-usage() {
  echo "up|Check OS, Cargo, and PGRX dependencies."
  echo "install|Build and install the extension locally (after up)."
  echo "reinstall|Clean, build, and install the extension locally (after up)."
  echo "test-jspg|Run pgrx integration tests."
  echo "test-validator|Run validator integration tests."
  echo "clean|Remove pgrx build artifacts."
}

jspg-flow() {
  case "$1" in
    up) up && rust-up && pgrx-up; return $?;; 
    down) pgrx-down && rust-down && down; return $?;; 
    build) build; return $?;; 
    install) install; return $?;; 
    reinstall) clean && install; return $?;; 
    test) test "${@:2}"; return $?;; 
    clean) clean; return $?;;
    *) return 127 ;;
  esac
}

register-flow "jspg"

dispatch "$@"