#!/bin/bash
# op-reference - Manage 1Password secret references for AI agents
# Usage: op-reference [list|get|copy|template|help]

set -e

SCRIPT_NAME="$(basename "$0")"
CONFIG_DIR="${HOME}/.config/op-ssh"
REFERENCES_FILE="${CONFIG_DIR}/references.conf"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Ensure config directory exists
mkdir -p "$CONFIG_DIR"

usage() {
    cat << EOF
${GREEN}1Password Reference Manager${NC} - Easy secret reference management for AI agents

${BLUE}Usage:${NC}
  $SCRIPT_NAME <command> [options]

${BLUE}Commands:${NC}
  ${GREEN}list${NC}                    List available vaults and SSH-related items
  ${GREEN}get <reference>${NC}         Retrieve a secret value from a reference
  ${GREEN}copy <reference>${NC}       Copy a reference to clipboard (requires xclip or wl-copy)
  ${GREEN}template${NC}                Create a new reference template file
  ${GREEN}add <name> <ref>${NC}        Save a named reference to config
  ${GREEN}resolve <name>${NC}         Resolve a named reference from config
  ${GREEN}env <file>${NC}              Load environment variables from 1Password references in file
  ${GREEN}check${NC}                   Verify 1Password CLI is authenticated
  ${GREEN}help${NC}                    Show this help message

${BLUE}Examples:${NC}
  $SCRIPT_NAME list
  $SCRIPT_NAME get "op://Private/PEGASUS-SSH/password"
  $SCRIPT_NAME copy "op://Private/API-Keys/openai"
  $SCRIPT_NAME add OPENAI_KEY "op://Private/API-Keys/openai"
  $SCRIPT_NAME resolve OPENAI_KEY

${YELLOW}Note:${NC} Requires 'op' CLI to be installed and authenticated.
        Run 'op signin' if not already logged in.
EOF
}

# Check if op CLI is available
check_op() {
    if ! command -v op &> /dev/null; then
        echo -e "${RED}Error: 1Password CLI (op) not found${NC}"
        echo "Install from: https://1password.com/downloads/command-line/"
        exit 1
    fi
}

# Check if authenticated
check_auth() {
    if ! op account list &> /dev/null; then
        echo -e "${YELLOW}Not authenticated to 1Password${NC}"
        echo "Run: op signin"
        exit 1
    fi
}

# List vaults and items
cmd_list() {
    check_op
    check_auth
    
    echo -e "${GREEN}=== Available Vaults ===${NC}"
    op vault list --format json 2>/dev/null | jq -r '.[].name' 2>/dev/null || \
        op vault list | head -20
    
    echo ""
    echo -e "${GREEN}=== SSH Key Items ===${NC}"
    op item list --categories "SSH Key" 2>/dev/null | head -20 || \
        echo "No SSH key items found"
    
    echo ""
    echo -e "${YELLOW}Tip: Use 'op item get <item-name>' to see fields and copy references${NC}"
}

# Get a secret value
cmd_get() {
    local reference="$1"
    if [[ -z "$reference" ]]; then
        echo -e "${RED}Error: No reference provided${NC}"
        echo "Usage: $SCRIPT_NAME get <reference>"
        exit 1
    fi
    
    check_op
    check_auth
    
    # Strip quotes if present
    reference="${reference//\"}"
    
    op read "$reference"
}

# Copy reference to clipboard
cmd_copy() {
    local reference="$1"
    if [[ -z "$reference" ]]; then
        echo -e "${RED}Error: No reference provided${NC}"
        exit 1
    fi
    
    check_op
    check_auth
    
    # Strip quotes if present  
    reference="${reference//\"}"
    
    # Detect clipboard tool
    local clipboard_cmd=""
    if command -v wl-copy &> /dev/null; then
        clipboard_cmd="wl-copy"
    elif command -v xclip &> /dev/null; then
        clipboard_cmd="xclip -selection clipboard"
    elif command -v pbcopy &> /dev/null; then
        clipboard_cmd="pbcopy"
    else
        echo -e "${YELLOW}No clipboard tool found. Reference:${NC}"
        echo "$reference"
        return 0
    fi
    
    echo -e "${GREEN}Copied to clipboard:${NC} $reference"
}

# Create a template file
cmd_template() {
    local template_file="${CONFIG_DIR}/env.template"
    
    cat > "$template_file" << 'EOF'
# 1Password Environment Variables Template
# Copy this to your project and fill in your references
# Usage: eval $(op-reference env .env.1pass)

# API Keys - replace with your actual references
OPENAI_API_KEY="op://Private/API-Keys/openai"
ANTHROPIC_API_KEY="op://Private/API-Keys/anthropic"
GITHUB_TOKEN="op://Private/GitHub/token"

# SSH Keys
SSH_KEY_PASSPHRASE="op://Private/PEGASUS-SSH/password"

# Database connections
DATABASE_URL="op://Private/Database/production"

# Cloud providers
AWS_ACCESS_KEY_ID="op://Private/AWS/access-key-id"
AWS_SECRET_ACCESS_KEY="op://Private/AWS/secret-access-key"
EOF

    echo -e "${GREEN}Created template:${NC} $template_file"
    echo -e "${YELLOW}Edit this file with your actual 1Password references${NC}"
}

# Save a named reference
cmd_add() {
    local name="$1"
    local reference="$2"
    
    if [[ -z "$name" || -z "$reference" ]]; then
        echo -e "${RED}Error: Name and reference required${NC}"
        echo "Usage: $SCRIPT_NAME add <name> <reference>"
        exit 1
    fi
    
    # Sanitize name - uppercase, alphanumeric and underscore only
    name="${name^^}"
    name="${name//[^A-Z0-9_]/}"
    
    echo "${name}=${reference}" >> "$REFERENCES_FILE"
    echo -e "${GREEN}Saved:${NC} $name -> $reference"
}

# Resolve a named reference
cmd_resolve() {
    local name="$1"
    
    if [[ -z "$name" ]]; then
        echo -e "${RED}Error: Name required${NC}"
        exit 1
    fi
    
    name="${name^^}"
    
    if [[ ! -f "$REFERENCES_FILE" ]]; then
        echo -e "${RED}No references configured${NC}"
        exit 1
    fi
    
    local reference
    reference=$(grep "^${name}=" "$REFERENCES_FILE" 2>/dev/null | cut -d'=' -f2-)
    
    if [[ -z "$reference" ]]; then
        echo -e "${RED}Reference '$name' not found${NC}"
        exit 1
    fi
    
    echo "$reference"
}

# Load env file with 1Password references
cmd_env() {
    local env_file="${1:-.env.1pass}"
    
    if [[ ! -f "$env_file" ]]; then
        echo -e "${RED}File not found: $env_file${NC}"
        echo "Run '$SCRIPT_NAME template' to create a template"
        exit 1
    fi
    
    check_op
    check_auth
    
    # Read file and resolve references
    while IFS= read -r line || [[ -n "$line" ]]; do
        # Skip comments and empty lines
        [[ "$line" =~ ^#.*$ ]] && continue
        [[ -z "$line" ]] && continue
        
        # Check if it contains an op reference
        if [[ "$line" =~ op:// ]]; then
            # Extract variable name and reference
            local varname="${line%%=*}"
            varname="${varname#export }"
            local reference="${line#*=}"
            reference="${reference//\"}"
            
            # Resolve the secret
            local value
            if value=$(op read "$reference" 2>/dev/null); then
                echo "export ${varname}='${value}'"
            else
                echo -e "${RED}# Failed to resolve: $reference${NC}" >&2
            fi
        else
            # Pass through non-op lines
            echo "$line"
        fi
    done < "$env_file"
}

# Check authentication status
cmd_check() {
    check_op
    
    echo -e "${BLUE}Checking 1Password CLI...${NC}"
    
    if op account list &> /dev/null; then
        echo -e "${GREEN}✓ Authenticated${NC}"
        op account list --format=json 2>/dev/null | jq -r '.[] | "  Account: \(.url) (\(.email))"' 2>/dev/null || \
            op account list | head -5
    else
        echo -e "${YELLOW}✗ Not authenticated${NC}"
        echo "Run: op signin"
        exit 1
    fi
}

# Main dispatch
main() {
    local cmd="${1:-help}"
    
    case "$cmd" in
        list|ls|l)
            cmd_list
            ;;
        get|g)
            shift
            cmd_get "$@"
            ;;
        copy|c)
            shift
            cmd_copy "$@"
            ;;
        template|t)
            cmd_template
            ;;
        add|a)
            shift
            cmd_add "$@"
            ;;
        resolve|r)
            shift
            cmd_resolve "$@"
            ;;
        env|e)
            shift
            cmd_env "$@"
            ;;
        check|status)
            cmd_check
            ;;
        help|--help|-h|*)
            usage
            ;;
    esac
}

main "$@"
