#!/usr/bin/env bash
# Mole Agent Linux Installer
# Supports native systemd installation and Docker-based container installation.

set -e

INSTALL_DIR="/opt/mole"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Formatting helper functions
info() { echo -e "\e[34m[INFO]\e[0m $*"; }
success() { echo -e "\e[32m[SUCCESS]\e[0m $*"; }
error() { echo -e "\e[31m[ERROR]\e[0m $*" >&2; exit 1; }
warn() { echo -e "\e[33m[WARNING]\e[0m $*"; }

echo "============================================="
echo "  Installing Mole Miner Scanner Agent"
echo "============================================="

# Ensure running as root or with sudo
if [ "$EUID" -ne 0 ]; then
  error "Please run this installer as root or with sudo."
fi

# Detect Package Manager
if [ -f /etc/debian_version ]; then
    PKG_MANAGER="apt"
elif [ -f /etc/redhat-release ]; then
    PKG_MANAGER="yum"
else
    PKG_MANAGER="unknown"
fi

# Interactive prompts must survive `curl ... | sudo bash`, where stdin is the
# script itself. Read from the terminal when one exists; otherwise fall back
# to the provided default so the install completes non-interactively.
HAS_TTY=false
[ -e /dev/tty ] && [ -r /dev/tty ] && HAS_TTY=true

prompt() { # prompt <message> <default>
    local answer=""
    if $HAS_TTY; then
        read -rp "$1" answer < /dev/tty || true
    fi
    echo "${answer:-$2}"
}

# Choice of installation type. Override with MOLE_INSTALL_METHOD=native|docker.
case "${MOLE_INSTALL_METHOD:-}" in
    native|1) INSTALL_METHOD=1 ;;
    docker|2) INSTALL_METHOD=2 ;;
    *)
        echo "Select installation method:"
        echo "1) Native Linux (Systemd Service)"
        echo "2) Docker Container"
        INSTALL_METHOD=$(prompt "Enter choice [1-2] (default: 1): " 1)
        ;;
esac
[ "$INSTALL_METHOD" = "1" ] || [ "$INSTALL_METHOD" = "2" ] || INSTALL_METHOD=1
$HAS_TTY || info "No terminal detected - using non-interactive defaults (method: $([ "$INSTALL_METHOD" = "1" ] && echo 'Native Systemd' || echo 'Docker'))."

create_config() {
    info "Configuring Agent Settings..."
    mkdir -p "$INSTALL_DIR"
    
    # Check if config exists, if not create one
    if [ ! -f "$INSTALL_DIR/config.yaml" ]; then
        if [ -f "$SCRIPT_DIR/config.yaml" ]; then
            cp "$SCRIPT_DIR/config.yaml" "$INSTALL_DIR/config.yaml"
        else
            cat <<EOF > "$INSTALL_DIR/config.yaml"
# Mole Agent Config
site_id: "REPLACE_WITH_YOUR_SITE_ID"
scan_range: "192.168.1.0/24"
main_app_url: "https://api.molehash.com"
api_key: "REPLACE_WITH_YOUR_SITE_API_KEY"
pickaxe_id: "REPLACE_WITH_YOUR_MOLE_ID"
client_id: "REPLACE_WITH_YOUR_CLIENT_ID"
timeout: 5
scan_ports:
  - 4028
  - 4029
  - 80
  - 8080
EOF
        fi
        
        # Configuration parameters: environment variables win, then the
        # terminal prompt (when there is one), then the default. Empty
        # answers keep the existing placeholder so a half-configured agent
        # fails loudly instead of reporting with blank credentials.
        CONFIG_SITE=${MOLE_SITE_ID:-$(prompt "Enter Site ID [site_a]: " site_a)}
        CONFIG_RANGE=${MOLE_SCAN_RANGE:-$(prompt "Enter IP Subnet Scan Range [192.168.1.0/24]: " 192.168.1.0/24)}
        CONFIG_API=${MOLE_APP_URL:-$(prompt "Enter Main App URL [https://api.molehash.com]: " https://api.molehash.com)}
        CONFIG_KEY=${MOLE_API_KEY:-$(prompt "Enter API Key (leave empty to fill in later): " "")}
        CONFIG_PICKAXE=${MOLE_PICKAXE_ID:-$(prompt "Enter Pickaxe ID (optional): " "")}
        CONFIG_CLIENT=${MOLE_CLIENT_ID:-$(prompt "Enter Client ID (optional): " "")}

        # Replace config variables in target file (skip empty answers)
        sed -i "s/site_id:.*/site_id: \"$CONFIG_SITE\"/g" "$INSTALL_DIR/config.yaml"
        sed -i "s|scan_range:.*|scan_range: \"$CONFIG_RANGE\"|g" "$INSTALL_DIR/config.yaml"
        sed -i "s|main_app_url:.*|main_app_url: \"$CONFIG_API\"|g" "$INSTALL_DIR/config.yaml"
        [ -n "$CONFIG_KEY" ] && sed -i "s/api_key:.*/api_key: \"$CONFIG_KEY\"/g" "$INSTALL_DIR/config.yaml"

        # Add pickaxe_id and client_id if provided
        if [ -n "$CONFIG_PICKAXE" ]; then
            if grep -q "pickaxe_id:" "$INSTALL_DIR/config.yaml"; then
                sed -i "s/pickaxe_id:.*/pickaxe_id: \"$CONFIG_PICKAXE\"/g" "$INSTALL_DIR/config.yaml"
            else
                echo "pickaxe_id: \"$CONFIG_PICKAXE\"" >> "$INSTALL_DIR/config.yaml"
            fi
        fi

        if [ -n "$CONFIG_CLIENT" ]; then
            if grep -q "client_id:" "$INSTALL_DIR/config.yaml"; then
                sed -i "s/client_id:.*/client_id: \"$CONFIG_CLIENT\"/g" "$INSTALL_DIR/config.yaml"
            else
                echo "client_id: \"$CONFIG_CLIENT\"" >> "$INSTALL_DIR/config.yaml"
            fi
        fi

        if [ -z "$CONFIG_KEY" ]; then
            warn "No API key set. Edit $INSTALL_DIR/config.yaml with your site_id and api_key"
            warn "(dashboard -> Settings -> Billing), then run: systemctl restart mole-agent"
        fi
    else
        success "Existing config.yaml found in $INSTALL_DIR. Preserving it."
        # Read the API URL from existing config to download/redeploy if needed
        CONFIG_API=$(grep "main_app_url:" "$INSTALL_DIR/config.yaml" | awk '{print $2}' | tr -d '"' | tr -d "'")
    fi
}

case "$INSTALL_METHOD" in
    1)
        info "Installing Native Linux dependencies..."
        if [ "$PKG_MANAGER" = "apt" ]; then
            apt-get update && apt-get install -y python3 python3-pip python3-yaml
        elif [ "$PKG_MANAGER" = "yum" ]; then
            yum install -y python3 python3-pip python3-pyyaml
        else
            warn "Unsupported package manager. Please ensure python3, pip, and python-yaml are installed manually."
        fi

        info "Installing Python dependencies (pyasic, aiohttp)..."
        pip3 install --upgrade pip
        pip3 install pyasic aiohttp pyyaml

        # Set up directories and files
        create_config
        
        if [ -f "$SCRIPT_DIR/mole_agent.py" ]; then
            cp "$SCRIPT_DIR/mole_agent.py" "$INSTALL_DIR/mole_agent.py"
        else
            info "Downloading agent code from $CONFIG_API/api/v1/moles/agent-code..."
            if ! curl -fsSL --connect-timeout 10 "$CONFIG_API/api/v1/moles/agent-code" -o "$INSTALL_DIR/mole_agent.py" \
               || ! grep -q "AGENT_VERSION" "$INSTALL_DIR/mole_agent.py"; then
                info "API not reachable - downloading latest release from agent.molehash.com..."
                curl -fsSL --connect-timeout 10 "https://agent.molehash.com/latest/mole_agent.py" -o "$INSTALL_DIR/mole_agent.py"
            fi
        fi
        chmod +x "$INSTALL_DIR/mole_agent.py"

        info "Configuring Systemd service..."
        cat <<EOF > /etc/systemd/system/mole-agent.service
[Unit]
Description=Mole Miner Scanner Service
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=$INSTALL_DIR
Environment=LOOP_INTERVAL=300
ExecStart=/usr/bin/python3 $INSTALL_DIR/mole_agent.py --config $INSTALL_DIR/config.yaml
Restart=always

[Install]
WantedBy=multi-user.target
EOF

        systemctl daemon-reload
        systemctl enable mole-agent.service
        systemctl start mole-agent.service
        
        success "Native Linux service 'mole-agent' installed and started successfully!"
        info "You can view logs using: journalctl -u mole-agent -f"
        ;;
        
    2)
        info "Checking Docker installation..."
        if ! command -v docker &> /dev/null; then
            error "Docker is not installed on this system. Please install Docker first."
        fi
        
        # Set up directories and config files
        create_config
        
        # Build the Docker image locally using a build context directory
        BUILD_DIR="/tmp/mole_build"
        rm -rf "$BUILD_DIR"
        mkdir -p "$BUILD_DIR"
        
        if [ -f "$SCRIPT_DIR/Dockerfile" ]; then
            cp "$SCRIPT_DIR/Dockerfile" "$BUILD_DIR/Dockerfile"
            cp "$SCRIPT_DIR/mole_agent.py" "$BUILD_DIR/mole_agent.py"
        else
            info "Downloading Dockerfile and agent code from remote API..."
            if ! curl -fsSL --connect-timeout 10 "$CONFIG_API/api/v1/moles/agent-code" -o "$BUILD_DIR/mole_agent.py" \
               || ! grep -q "AGENT_VERSION" "$BUILD_DIR/mole_agent.py"; then
                info "API not reachable - downloading latest release from agent.molehash.com..."
                curl -fsSL --connect-timeout 10 "https://agent.molehash.com/latest/mole_agent.py" -o "$BUILD_DIR/mole_agent.py"
            fi
            cat <<EOF > "$BUILD_DIR/Dockerfile"
FROM python:3.11-slim
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends gcc python3-dev && rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir --upgrade pip && pip install --no-cache-dir pyasic pyyaml aiohttp
COPY mole_agent.py /app/mole_agent.py
ENV LOOP_INTERVAL=300
ENV CONFIG_PATH=/app/config.yaml
CMD ["python", "mole_agent.py", "--config", "/app/config.yaml"]
EOF
        fi
        
        # Build the Docker image
        info "Building Mole Agent Docker image..."
        docker build -t mole-agent "$BUILD_DIR"
        rm -rf "$BUILD_DIR"
        
        # Clean existing container
        if docker ps -a --format '{{.Names}}' | grep -Eq "^mole-agent$"; then
            info "Removing existing mole-agent container..."
            docker rm -f mole-agent
        fi
        
        # Launch Docker container
        info "Launching Docker container with 5-minute loop..."
        docker run -d \
            --name mole-agent \
            --restart always \
            -v "$INSTALL_DIR/config.yaml:/app/config.yaml" \
            -e LOOP_INTERVAL=300 \
            mole-agent
            
        success "Docker mole-agent container created and running!"
        info "You can view logs using: docker logs -f mole-agent"
        ;;
        
    *)
        error "Invalid selection. Exiting."
        ;;
esac
