#!/bin/bash

set -euo pipefail

BOLD='\033[0;1m'

command_exists() {
  command -v "$1" > /dev/null 2>&1
}

ARG_CLAUDE_CODE_VERSION='${ARG_CLAUDE_CODE_VERSION}'
ARG_WORKDIR='${ARG_WORKDIR}'
ARG_INSTALL_CLAUDE_CODE='${ARG_INSTALL_CLAUDE_CODE}'
ARG_CLAUDE_BINARY_PATH='${ARG_CLAUDE_BINARY_PATH}'
ARG_CLAUDE_BINARY_PATH="$${ARG_CLAUDE_BINARY_PATH/#\~/$HOME}"
ARG_CLAUDE_BINARY_PATH="$${ARG_CLAUDE_BINARY_PATH//\$HOME/$HOME}"
ARG_MCP=$(echo -n '${ARG_MCP}' | base64 -d)
ARG_MCP_CONFIG_REMOTE_PATH=$(echo -n '${ARG_MCP_CONFIG_REMOTE_PATH}' | base64 -d)
ARG_ENABLE_AI_GATEWAY='${ARG_ENABLE_AI_GATEWAY}'
ARG_MANAGED_SETTINGS_JSON=$(echo -n '${ARG_MANAGED_SETTINGS_JSON}' | base64 -d)

export PATH="$${ARG_CLAUDE_BINARY_PATH}:$PATH"

echo "--------------------------------"

printf "ARG_CLAUDE_CODE_VERSION: %s\n" "$${ARG_CLAUDE_CODE_VERSION}"
printf "ARG_WORKDIR: %s\n" "$${ARG_WORKDIR}"
printf "ARG_INSTALL_CLAUDE_CODE: %s\n" "$${ARG_INSTALL_CLAUDE_CODE}"
printf "ARG_CLAUDE_BINARY_PATH: %s\n" "$${ARG_CLAUDE_BINARY_PATH}"
printf "ARG_MCP: %s\n" "$${ARG_MCP}"
printf "ARG_MCP_CONFIG_REMOTE_PATH: %s\n" "$${ARG_MCP_CONFIG_REMOTE_PATH}"
printf "ARG_ENABLE_AI_GATEWAY: %s\n" "$${ARG_ENABLE_AI_GATEWAY}"
printf "ARG_MANAGED_SETTINGS_JSON: %s\n" "$${ARG_MANAGED_SETTINGS_JSON}"

echo "--------------------------------"

function add_mcp_servers() {
  local mcp_json="$1"
  local source_desc="$2"

  while IFS= read -r server_name && IFS= read -r server_json; do
    echo "------------------------"
    echo "Executing: claude mcp add-json --scope user \"$${server_name}\" '$${server_json}' ($${source_desc})"
    claude mcp add-json --scope user "$${server_name}" "$${server_json}" || echo "Warning: Failed to add MCP server '$${server_name}', continuing..."
    echo "------------------------"
    echo ""
  done < <(echo "$${mcp_json}" | jq -r '.mcpServers | to_entries[] | .key, (.value | @json)')
}

function add_path_to_shell_profiles() {
  local path_dir="$1"

  for profile in "$HOME/.profile" "$HOME/.bash_profile" "$HOME/.bashrc" "$HOME/.zprofile" "$HOME/.zshrc"; do
    if [ -f "$${profile}" ]; then
      if ! grep -q "$${path_dir}" "$${profile}" 2> /dev/null; then
        echo "export PATH=\"\$PATH:$${path_dir}\"" >> "$${profile}"
        echo "Added $${path_dir} to $${profile}"
      fi
    fi
  done

  local fish_config="$HOME/.config/fish/config.fish"
  if [ -f "$${fish_config}" ]; then
    if ! grep -q "$${path_dir}" "$${fish_config}" 2> /dev/null; then
      echo "fish_add_path $${path_dir}" >> "$${fish_config}"
      echo "Added $${path_dir} to $${fish_config}"
    fi
  fi
}

function ensure_claude_in_path() {
  local CLAUDE_BIN=""
  if command -v claude > /dev/null 2>&1; then
    CLAUDE_BIN=$(command -v claude)
  elif [ -x "$${ARG_CLAUDE_BINARY_PATH}/claude" ]; then
    CLAUDE_BIN="$${ARG_CLAUDE_BINARY_PATH}/claude"
  elif [ -x "$HOME/.local/bin/claude" ]; then
    CLAUDE_BIN="$HOME/.local/bin/claude"
  fi

  if [ -z "$${CLAUDE_BIN}" ] || [ ! -x "$${CLAUDE_BIN}" ]; then
    echo "Warning: Could not find claude binary"
    return
  fi

  local CLAUDE_DIR
  CLAUDE_DIR=$(dirname "$${CLAUDE_BIN}")

  if [ -n "$${CODER_SCRIPT_BIN_DIR:-}" ] && [ ! -e "$${CODER_SCRIPT_BIN_DIR}/claude" ]; then
    ln -s "$${CLAUDE_BIN}" "$${CODER_SCRIPT_BIN_DIR}/claude"
    echo "Created symlink: $${CODER_SCRIPT_BIN_DIR}/claude -> $${CLAUDE_BIN}"
  fi

  add_path_to_shell_profiles "$${CLAUDE_DIR}"
}

function install_claude_code_cli() {
  if [ "$${ARG_INSTALL_CLAUDE_CODE}" != "true" ]; then
    echo "Skipping Claude Code installation as per configuration."
    ensure_claude_in_path
    return
  fi

  echo "Installing Claude Code via official installer"
  set +e
  curl -fsSL claude.ai/install.sh | bash -s -- "$${ARG_CLAUDE_CODE_VERSION}" 2>&1
  CURL_EXIT=$${PIPESTATUS[0]}
  set -e
  if [ $${CURL_EXIT} -ne 0 ]; then
    echo "Claude Code installer failed with exit code $${CURL_EXIT}"
  fi
  echo "Installed Claude Code successfully. Version: $(claude --version || echo 'unknown')"

  ensure_claude_in_path
}

function setup_claude_configurations() {
  if [ -n "$${ARG_WORKDIR}" ] && [ ! -d "$${ARG_WORKDIR}" ]; then
    echo "Warning: The specified folder '$${ARG_WORKDIR}' does not exist."
    echo "Creating the folder..."
    mkdir -p "$${ARG_WORKDIR}"
    echo "Folder created successfully."
  fi

  module_path="$HOME/.coder-modules/coder/claude-code"
  mkdir -p "$${module_path}"

  if [ "$${ARG_MCP}" != "" ]; then
    add_mcp_servers "$${ARG_MCP}" "from module input"
  fi

  if [ -n "$${ARG_MCP_CONFIG_REMOTE_PATH}" ] && [ "$${ARG_MCP_CONFIG_REMOTE_PATH}" != "[]" ]; then
    for url in $(echo "$${ARG_MCP_CONFIG_REMOTE_PATH}" | jq -r '.[]'); do
      echo "Fetching MCP configuration from: $${url}"
      mcp_json=$(curl -fsSL "$${url}") || {
        echo "Warning: Failed to fetch MCP configuration from '$${url}', continuing..."
        continue
      }
      if ! echo "$${mcp_json}" | jq -e '.mcpServers' > /dev/null 2>&1; then
        echo "Warning: Invalid MCP configuration from '$${url}' (missing mcpServers), continuing..."
        continue
      fi
      add_mcp_servers "$${mcp_json}" "from $${url}"
    done
  fi

}

function write_managed_settings() {
  if [ -z "$${ARG_MANAGED_SETTINGS_JSON}" ]; then
    return
  fi

  local dropin_dir="/etc/claude-code/managed-settings.d"
  local target="$${dropin_dir}/10-coder.json"

  if ! echo "$${ARG_MANAGED_SETTINGS_JSON}" | jq empty 2> /dev/null; then
    echo "Warning: managed_settings is not valid JSON, skipping policy write"
    return
  fi

  if command_exists sudo; then
    sudo mkdir -p "$${dropin_dir}"
    echo "$${ARG_MANAGED_SETTINGS_JSON}" | sudo tee "$${target}" > /dev/null
    sudo chmod 0644 "$${target}"
  else
    mkdir -p "$${dropin_dir}"
    echo "$${ARG_MANAGED_SETTINGS_JSON}" > "$${target}"
    chmod 0644 "$${target}"
  fi

  echo "Wrote Claude Code managed settings to $${target}"
}

function configure_standalone_mode() {
  echo "Configuring Claude Code for standalone mode..."

  if [ -z "$${ANTHROPIC_API_KEY:-}" ] && [ -z "$${CLAUDE_CODE_OAUTH_TOKEN:-}" ] && [ "$${ARG_ENABLE_AI_GATEWAY}" = "false" ]; then
    echo "Note: No authentication configured (anthropic_api_key, claude_code_oauth_token, enable_ai_gateway), skipping onboarding bypass"
    return
  fi

  local claude_config="$HOME/.claude.json"

  if [ -f "$${claude_config}" ]; then
    echo "Updating existing Claude configuration at $${claude_config}"

    jq '.autoUpdaterStatus = "disabled" |
        .hasAcknowledgedCostThreshold = true |
        .hasCompletedOnboarding = true' \
      "$${claude_config}" > "$${claude_config}.tmp" && mv "$${claude_config}.tmp" "$${claude_config}"
  else
    echo "Creating new Claude configuration at $${claude_config}"
    cat > "$${claude_config}" << EOF
{
  "autoUpdaterStatus": "disabled",
  "hasAcknowledgedCostThreshold": true,
  "hasCompletedOnboarding": true
}
EOF
  fi

  if [ -n "$${ARG_WORKDIR}" ]; then
    echo "Pre-accepting trust dialog for $${ARG_WORKDIR}"
    jq --arg workdir "$${ARG_WORKDIR}" \
      '.projects[$workdir].hasCompletedProjectOnboarding = true |
        .projects[$workdir].hasTrustDialogAccepted = true' \
      "$${claude_config}" > "$${claude_config}.tmp" && mv "$${claude_config}.tmp" "$${claude_config}"
  fi

  echo "Standalone mode configured successfully"
}

install_claude_code_cli
setup_claude_configurations
write_managed_settings
configure_standalone_mode
