#!/bin/bash
set -e  # Exit on any error

# Home Information - Single Command Installer
# Installs and runs Home Information with minimal user interaction
# Requires: Docker

# Configuration
DOCKER_IMAGE="ghcr.io/cassandra/home-information"  # GitHub Container Registry
DOCKER_TAG="${1:-latest}"  # Allow override for testing (default: latest)
CONTAINER_NAME="hi"
EXTERNAL_PORT="9411"
HI_HOME="${HOME}/.hi"
ENV_DIR="${HI_HOME}/env"
DATABASE_DIR="${HI_HOME}/database"
MEDIA_DIR="${HI_HOME}/media"
ENV_FILE="${ENV_DIR}/local.env"

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

print_header() {
    echo -e "${BLUE}================================${NC}"
    echo -e "${BLUE} Home Information Installer${NC}"
    echo -e "${BLUE}================================${NC}"
}

print_success() {
    echo -e "${GREEN}✓ $1${NC}"
}

print_info() {
    echo -e "${BLUE}• $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠ $1${NC}"
}

print_error() {
    echo -e "${RED}✗ $1${NC}"
    exit 1
}

# Check if Docker is installed and running
check_docker() {
    print_info "Checking Docker installation..."
    
    if ! command -v docker &> /dev/null; then
        print_error "Docker is not installed. Please install Docker first: https://docs.docker.com/get-docker/"
    fi
    
    if ! docker info &> /dev/null; then
        print_error "Docker is not running. Please start Docker and try again."
    fi
    
    print_success "Docker is installed and running"
}

# Check if Python3 is installed (needed for secure secret generation)
check_python() {
    print_info "Checking Python 3 installation..."
    
    if ! command -v python3 &> /dev/null; then
        print_error "Python 3.6+ is required but not installed. Please install Python 3.6 or later."
    fi
    
    print_success "Python 3 is installed"
}

# Generate cryptographically secure Django secret key
generate_secret_key() {
    python3 -c "
import secrets
import string
chars = string.ascii_letters + string.digits + string.punctuation
print(''.join(secrets.choice(chars) for _ in range(50)))
"
}

# Generate memorable admin password
generate_admin_password() {
    python3 -c "
import secrets
words = [
    'apple', 'banana', 'cherry', 'delta', 'eagle', 'falcon', 'grape', 
    'hunter', 'island', 'joker', 'kitten', 'lemon', 'melon', 'ninja', 'ocean',
    'piano', 'queen', 'robot', 'stone', 'tiger', 'unity', 'voice', 'water',
    'xenon', 'yacht', 'zebra', 'anchor', 'bridge', 'camera', 'dream', 'energy'
]
chosen_words = [secrets.choice(words) for _ in range(3)]
random_number = str(secrets.randbelow(1000))
chosen_words.append(random_number)
print('-'.join(chosen_words))
"
}

# Create required directories
create_directories() {
    print_info "Creating directories..."
    
    # Create directories with proper permissions
    mkdir -p "${ENV_DIR}"
    mkdir -p "${DATABASE_DIR}"
    mkdir -p "${MEDIA_DIR}"
    
    # Secure the env directory (user only)
    chmod 700 "${ENV_DIR}"
    
    print_success "Directories created: ${HI_HOME}"
}

# Generate environment file
create_env_file() {
    print_info "Generating configuration and secrets..."
    
    # Check if env file already exists
    if [[ -f "${ENV_FILE}" ]]; then
        print_warning "Configuration file already exists: ${ENV_FILE}"
        read -p "Do you want to overwrite it? (y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            print_error "Installation cancelled. Remove ${ENV_FILE} to start fresh."
        fi
        
        # Create backup (using portable date format)
        TIMESTAMP=$(date "+%Y%m%d_%H%M%S")
        BACKUP_FILE="${ENV_FILE}.BAK.${TIMESTAMP}"
        cp "${ENV_FILE}" "${BACKUP_FILE}"
        print_info "Backup created: ${BACKUP_FILE}"
    fi
    
    # Generate secrets
    DJANGO_SECRET_KEY=$(generate_secret_key)
    DJANGO_ADMIN_PASSWORD=$(generate_admin_password)
    
    # Create environment file
    cat > "${ENV_FILE}" << EOF
# Home Information Environment Configuration
# Generated by install.sh on $(date)

# Core Django Settings
DJANGO_SETTINGS_MODULE=hi.settings.local
DJANGO_SERVER_PORT=8000
DJANGO_SECRET_KEY=${DJANGO_SECRET_KEY}

# Admin User (for Django admin interface)
DJANGO_SUPERUSER_EMAIL=admin@example.com
DJANGO_SUPERUSER_PASSWORD=${DJANGO_ADMIN_PASSWORD}

# Data Paths (inside Docker container)
HI_DB_PATH=/data/database
HI_MEDIA_PATH=/data/media

# Redis Configuration
HI_REDIS_HOST=127.0.0.1
HI_REDIS_PORT=6379
HI_REDIS_KEY_PREFIX=

# Authentication (disabled for simple setup)
HI_SUPPRESS_AUTHENTICATION=true

# Email Settings (disabled for simple setup)
HI_EMAIL_SUBJECT_PREFIX=
HI_DEFAULT_FROM_EMAIL=
HI_SERVER_EMAIL=
HI_EMAIL_HOST=
HI_EMAIL_PORT=587
HI_EMAIL_HOST_USER=
HI_EMAIL_HOST_PASSWORD=
HI_EMAIL_USE_TLS=false
HI_EMAIL_USE_SSL=false

# Network Configuration (for localhost only)
HI_EXTRA_HOST_URLS=
HI_EXTRA_CSP_URLS=
EOF
    
    # Secure the env file
    chmod 600 "${ENV_FILE}"
    
    print_success "Configuration file created: ${ENV_FILE}"
    
    # Store admin password for display later
    ADMIN_PASSWORD="${DJANGO_ADMIN_PASSWORD}"
}

# Pull Docker image
pull_docker_image() {
    print_info "Pulling Home Information Docker image..."
    
    if docker pull "${DOCKER_IMAGE}:${DOCKER_TAG}"; then
        print_success "Docker image pulled successfully"
    else
        print_error "Failed to pull Docker image. Please check your internet connection."
    fi
}

# Stop any existing container
stop_existing_container() {
    if docker ps -a --format 'table {{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
        print_info "Stopping existing container..."
        docker stop "${CONTAINER_NAME}" 2>/dev/null || true
        docker rm "${CONTAINER_NAME}" 2>/dev/null || true
        print_success "Existing container removed"
    fi
}

# Start the container
start_container() {
    print_info "Starting Home Information container..."
    
    docker run -d \
        --name "${CONTAINER_NAME}" \
        --restart unless-stopped \
        --env-file "${ENV_FILE}" \
        -v "${DATABASE_DIR}:/data/database" \
        -v "${MEDIA_DIR}:/data/media" \
        -p "${EXTERNAL_PORT}:8000" \
        "${DOCKER_IMAGE}:${DOCKER_TAG}"
    
    print_success "Container started successfully"
}

# Wait for application to be ready
wait_for_app() {
    print_info "Waiting for application to start (this may take a minute)..."
    
    # Wait up to 60 seconds for the app to be ready
    for i in {1..60}; do
        if curl -s "http://localhost:${EXTERNAL_PORT}" > /dev/null 2>&1; then
            print_success "Application is ready!"
            return 0
        fi
        sleep 1
        if [ $((i % 10)) -eq 0 ]; then
            print_info "Still waiting... (${i}s)"
        fi
    done
    
    print_warning "Application may still be starting. Check docker logs hi for details."
}

# Display success message
show_success() {
    echo
    echo -e "${GREEN}================================${NC}"
    echo -e "${GREEN} Installation Complete!${NC}"
    echo -e "${GREEN}================================${NC}"
    echo
    echo -e "${BLUE}🌐 Access your Home Information system:${NC}"
    echo -e "   ${BLUE}http://localhost:${EXTERNAL_PORT}${NC}"
    echo
    echo -e "${BLUE}🔐 Admin credentials:${NC}"
    echo -e "   Email: admin@example.com"
    echo -e "   Password: ${ADMIN_PASSWORD}"
    echo
    echo -e "${BLUE}📁 Your data is stored in:${NC}"
    echo -e "   Database: ${DATABASE_DIR}"
    echo -e "   Uploads: ${MEDIA_DIR}"
    echo
    echo -e "${BLUE}🔧 Useful commands:${NC}"
    echo -e "   View logs: docker logs hi"
    echo -e "   Stop: docker stop hi"
    echo -e "   Start: docker start hi"
    echo
    echo -e "${GREEN}IMPORTANT: Save your admin credentials securely!${NC}"
    echo
}

# Main installation function
main() {
    print_header
    
    check_docker
    check_python
    create_directories
    create_env_file
    pull_docker_image
    stop_existing_container
    start_container
    wait_for_app
    show_success
}

# Run main function
main "$@"