#!/usr/bin/env bash
#
# git.setup.sh
# Git Setup: macOS Dev → Remote Linux Server
# Author: Rick B
# Usage:
#   ./git.setup.sh                 # interactive menu
#   ./git.setup.sh mac-setup       # run macOS setup only
#   ./git.setup.sh server-setup    # run server bare-repo setup only
#   ./git.setup.sh ssh-setup       # run SSH key + copy only
#   ./git.setup.sh new-app myapp   # create & push a new app repo
#   ./git.setup.sh clone-on-server myapp
#   ./git.setup.sh dotfiles-setup  # set up dotfiles bare repo
#

set -euo pipefail

# -----------------------------
# Configuration (edit as needed)
# -----------------------------
GIT_USER_MAC="Rick Butare"
GIT_EMAIL_MAC="rickbeach08@gmail.com"

GIT_USER_SRV="${GIT_USER_MAC}"
GIT_EMAIL_SRV="ricklakehouse@gmail.com"

SERVER_USER="intel145"
SERVER_IP="209.182.212.74"
SERVER_GIT_DIR="/home/intel145/websites/gitrepo"
SERVER_APPS_DIR="$HOME/websites/apps"

#echo '#key: gq9ben0hye@hze_AGM';
#ssh  -p 2222 intel145@209.182.212.74 -i /Users/rbutare/.ssh/id_rsaNew1

DEFAULT_BRANCH="main"
EDITOR="nano"

# -----------------------------
# Helpers
# -----------------------------
info() {
  echo "🔹 $*"
}

warn() {
  echo "⚠️  $*" >&2
}

die() {
  echo "❌ $*" >&2
  exit 1
}

require_cmd() {
  local cmd="$1"
  if ! command -v "$cmd" >/dev/null 2>&1; then
    die "Required command not found: $cmd"
  fi
}

ssh_url() {
  local repo_name="$1"
  echo "ssh://${SERVER_USER}@${SERVER_IP}${SERVER_GIT_DIR}/${repo_name}.git"
}

# -----------------------------
# 1. macOS Git Setup
# -----------------------------
mac_setup() {
  info "Setting up Git on macOS..."

  require_cmd git

  git config --global user.name "$GIT_USER_MAC"
  git config --global user.email "$GIT_EMAIL_MAC"
  git config --global init.defaultBranch "$DEFAULT_BRANCH"
  git config --global pull.rebase true
  git config --global core.editor "$EDITOR"

  info "Git identity configured:"
  git config --global --list | grep -E '^(user\.|init\.|pull\.|core\.editor)' || true
}

# -----------------------------
# 2. Linux Server: Bare Repos Setup
# -----------------------------
server_setup() {
  info "Setting up bare repositories on Linux server..."

  # This is intended to run on the server itself.
  # If you run it from macOS, wrap it in an ssh block or copy script to server.

  require_cmd git

  # Create base directory for bare repos
  if [[ ! -d "$SERVER_GIT_DIR" ]]; then
    info "Creating $SERVER_GIT_DIR"
    mkdir -p "$SERVER_GIT_DIR"
  fi
  # Ensure ownership (may need sudo if run as root or different user)
  # sudo chown -R "$USER:$USER" "$SERVER_GIT_DIR"  # uncomment if needed

  # Default apps to initialize; you can pass overrides via args if desired
  local repos=("app1" "app2" "system-configs")

  for repo in "${repos[@]}"; do
    local repo_path="${SERVER_GIT_DIR}/${repo}.git"
    if [[ -d "$repo_path" ]]; then
      warn "Repo already exists: $repo_path"
    else
      info "Creating bare repo: $repo_path"
      git init --bare "$repo_path"
    fi
  done

  info "Bare repos created under $SERVER_GIT_DIR"
}

# -----------------------------
# 3. SSH Key Setup (macOS → Server)
# -----------------------------
ssh_setup() {
  info "Setting up SSH access from macOS to Linux server..."

  require_cmd ssh-keygen
  require_cmd ssh-copy-id
  require_cmd ssh

  local key_comment="ricklakehouse@gmail.com"
  local key_path="$HOME/.ssh/id_ed25519"

  if [[ -f "$key_path" ]]; then
    warn "SSH key already exists at $key_path"
  else
    info "Generating Ed25519 SSH key..."
    ssh-keygen -t ed25519 -C "$key_comment" -f "$key_path" -N ""
  fi

  info "Copying public key to server ${SERVER_USER}@${SERVER_IP}..."
  ssh-copy-id "${SERVER_USER}@${SERVER_IP}"

  info "Testing SSH connection..."
  #ORIG ssh -o BatchMode=yes -o ConnectTimeout=5 "${SERVER_USER}@${SERVER_IP}" 'echo "SSH OK"' || \
  ssh -p 2222 -o BatchMode=yes -o ConnectTimeout=5 "${SERVER_USER}@${SERVER_IP}" 'echo "SSH OK"' || \
    die "SSH test failed. Check key and server access."

  info "SSH setup complete."
}
testSsh() {
  info "Testing SSH connection..."
  #ssh -o BatchMode=yes -o ConnectTimeout=5 "${SERVER_USER}@${SERVER_IP}" 'echo "SSH OK"' || \
  #echo ssh -p 2222 -o BatchMode=yes -o ConnectTimeout=5 "${SERVER_USER}@${SERVER_IP}" 'echo "SSH OK"' || \
  ssh -p 2222 -o BatchMode=yes -o ConnectTimeout=5 "${SERVER_USER}@${SERVER_IP}" 'echo "SSH OK"' || \
    die "SSH test failed. Check key and server access."

  info "SSH setup complete."
}

# -----------------------------
# 4. Create & Push New App Repo (macOS)
# -----------------------------
new_app() {
  local app_name="${1:-}"
  [[ -n "$app_name" ]] || die "Usage: $0 new-app <app-name>"

  local app_dir="$HOME/dev/$app_name"

  info "Creating new app repo: $app_name at $app_dir"

  require_cmd git

  if [[ -d "$app_dir" ]]; then
    warn "Directory already exists: $app_dir"
  else
    mkdir -p "$app_dir"
  fi

  cd "$app_dir"

  if [[ -d ".git" ]]; then
    warn "Git repo already initialized in $app_dir"
  else
    git init
    git branch -M "$DEFAULT_BRANCH"
  fi

  local remote_url
  remote_url="$(ssh_url "$app_name")"

  # Remove existing origin if present and re-add
  if git remote get-url origin >/dev/null 2>&1; then
    git remote remove origin
  fi
  git remote add origin "$remote_url"

  if [[ ! -f "README.md" ]]; then
    echo "# $app_name" > README.md
  fi

  git add .
  git commit --allow-empty -m "Initial commit" || true

  info "Pushing to remote: $remote_url"
  git push -u origin "$DEFAULT_BRANCH"

  info "App repo '$app_name' created and pushed."
}

# -----------------------------
# 5. Clone Repo on Server (for deployment)
# -----------------------------
clone_on_server() {
  local app_name="${1:-}"
  [[ -n "$app_name" ]] || die "Usage: $0 clone-on-server <app-name>"

  info "Cloning $app_name on server into $SERVER_APPS_DIR/$app_name"

  # This function assumes it runs on the server itself.
  # For remote use, wrap in ssh or copy script to server.

  require_cmd git

  local src="/srv/git/${app_name}.git"
  local dest="${SERVER_APPS_DIR}/${app_name}"

  if [[ ! -d "$src" ]]; then
    die "Bare repo not found: $src"
  fi

  if [[ -d "$dest" ]]; then
    warn "Destination already exists: $dest"
    info "To update, run: cd $dest && git pull"
    return 0
  fi

  mkdir -p "$SERVER_APPS_DIR"
  git clone "$src" "$dest"

  info "Repo cloned to $dest"
}

# -----------------------------
# 6. Dotfiles Bare Repo Setup
# -----------------------------
dotfiles_setup() {
  info "Setting up dotfiles bare repo..."

  require_cmd git

  local dotfiles_dir="$HOME/.dotfiles"
  local dotfiles_remote_url
  dotfiles_remote_url="$(ssh_url "dotfiles")"

  # Initialize bare repo for dotfiles if not present
  if [[ ! -d "$dotfiles_dir" ]]; then
    info "Creating bare dotfiles repo at $dotfiles_dir"
    git init --bare "$dotfiles_dir"
  else
    warn "Dotfiles bare repo already exists at $dotfiles_dir"
  fi

  # Define alias helper (printed to user; cannot persist in current shell)
  local alias_cmd="alias dotfiles='git --git-dir=$dotfiles_dir --work-tree=$HOME'"
  info "Add this to your ~/.bashrc or ~/.zshrc:"
  echo "  $alias_cmd"

  # Show example usage
  cat <<'EOF'

Example usage (after adding alias and reloading shell):
  dotfiles add ~/.gitconfig ~/.bashrc ~/.ssh/config
  dotfiles commit -m "Add dotfiles"
  dotfiles remote add origin ssh://user@server-ip/srv/git/dotfiles.git
  dotfiles push -u origin main

On server (restore):
  git clone --bare ssh://user@server-ip/srv/git/dotfiles.git ~/.dotfiles
  alias dotfiles='git --git-dir=$HOME/.dotfiles --work-tree=$HOME'
  dotfiles checkout
EOF
}

# -----------------------------
# 7. Daily Workflow Helper (info only)
# -----------------------------
workflow_help() {
  cat <<'EOF'
Daily Git Workflow (reference)

Start work:
  cd ~/dev/myapp

Check status:
  git status

Stage changes:
  git add .

Commit:
  git commit -m "Describe change"

Push to server:
  git push

Pull on server:
  cd ~/apps/myapp && git pull

View history:
  git log --oneline --graph

Tag a release:
  git tag -a v1.0.0 -m "Release 1.0"
  git push --tags

Create feature branch:
  git checkout -b feature/new-ui

Merge to main:
  git checkout main && git merge feature/new-ui
EOF
}

# -----------------------------
# CLI / Main
# -----------------------------
usage() {
  cat <<EOF
Usage: $0 <command> [args...]

Commands:
  mac-setup              Set up Git on macOS (identity, defaults)
  server-setup           Create bare repos on Linux server (/srv/git)
  ssh-setup              Generate SSH key and copy to server
  new-app <app-name>     Create & push a new app repo from macOS
  clone-on-server <app>  Clone a bare repo into ~/apps/<app> on server
  dotfiles-setup         Set up dotfiles bare repo and alias instructions
  workflow               Show daily workflow reference
  help                   Show this help

If run without arguments, an interactive menu is shown.
EOF
}

interactive_menu() {
  while true; do
    cat <<'EOF'

Git Setup Guide – Menu
1) macOS Git setup
2) Server bare-repo setup (run on server)
3) SSH key + copy to server
4) Create & push new app repo
5) Clone repo on server (for deployment)
6) Dotfiles bare repo setup
7) Show daily workflow
8) Test ssh
0) Exit

EOF
    read -rp "Choose an option: " choice
    case "$choice" in
      1) mac_setup ;;
      2) server_setup ;;
      3) ssh_setup ;;
      4)
        read -rp "App name: " app
        new_app "$app"
        ;;
      5)
        read -rp "App name: " app
        clone_on_server "$app"
        ;;
      6) dotfiles_setup ;;
      7) workflow_help ;;
      8) testSsh ;;
      0) exit 0 ;;
      *) warn "Invalid option" ;;
    esac
  done
}

main() {
  local cmd="${1:-}"
  shift || true

  case "$cmd" in
    mac-setup)
      mac_setup
      ;;
    server-setup)
      server_setup
      ;;
    ssh-setup)
      ssh_setup
      ;;
    new-app)
      new_app "$@"
      ;;
    clone-on-server)
      clone_on_server "$@"
      ;;
    dotfiles-setup)
      dotfiles_setup
      ;;
    workflow)
      workflow_help
      ;;
    help|--help|-h|"")
      if [[ -z "$cmd" ]]; then
        interactive_menu
      else
        usage
      fi
      ;;
    *)
      warn "Unknown command: $cmd"
      usage
      exit 1
      ;;
  esac
}

main "$@"
