#!/bin/bash

# Fixture Manager Installation Script
# Comprehensive installation script for Linux servers

set -e  # Exit on any error

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

# Configuration
PROJECT_NAME="fixture-manager"
SERVICE_NAME="fixture-daemon"
INSTALL_DIR="/opt/fixture-manager"
DATA_DIR="/var/lib/fixture-daemon"
LOG_DIR="/var/log"
CONFIG_DIR="/etc/fixture-manager"
USER="fixture"
GROUP="fixture"

# Functions
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "This script must be run as root"
        exit 1
    fi
}

detect_os() {
    if [[ -f /etc/os-release ]]; then
        . /etc/os-release
        OS=$NAME
        VER=$VERSION_ID
    else
        log_error "Cannot detect operating system"
        exit 1
    fi
    
    log_info "Detected OS: $OS $VER"
}

install_dependencies() {
    log_info "Installing system dependencies..."
    
    if [[ "$OS" == *"Ubuntu"* ]] || [[ "$OS" == *"Debian"* ]]; then
        apt-get update
        apt-get install -y \
            python3 \
            python3-pip \
            python3-venv \
            python3-dev \
            mysql-server \
            mysql-client \
            libmysqlclient-dev \
            nginx \
            supervisor \
            git \
            curl \
            wget \
            unzip \
            build-essential \
            pkg-config
            
    elif [[ "$OS" == *"CentOS"* ]] || [[ "$OS" == *"Red Hat"* ]] || [[ "$OS" == *"Rocky"* ]]; then
        yum update -y
        yum install -y \
            python3 \
            python3-pip \
            python3-devel \
            mysql-server \
            mysql-devel \
            nginx \
            supervisor \
            git \
            curl \
            wget \
            unzip \
            gcc \
            gcc-c++ \
            make \
            pkgconfig
            
    else
        log_error "Unsupported operating system: $OS"
        exit 1
    fi
    
    log_success "System dependencies installed"
}

create_user() {
    log_info "Creating system user and group..."
    
    # Create group if it doesn't exist
    if ! getent group $GROUP > /dev/null 2>&1; then
        groupadd --system $GROUP
        log_success "Created group: $GROUP"
    fi
    
    # Create user if it doesn't exist
    if ! getent passwd $USER > /dev/null 2>&1; then
        useradd --system --gid $GROUP --home-dir $DATA_DIR --shell /bin/false $USER
        log_success "Created user: $USER"
    fi
}

create_directories() {
    log_info "Creating directories..."
    
    # Create main directories
    mkdir -p $INSTALL_DIR
    mkdir -p $DATA_DIR/{uploads,backups,logs}
    mkdir -p $CONFIG_DIR
    mkdir -p $LOG_DIR
    
    # Set ownership and permissions
    chown -R $USER:$GROUP $INSTALL_DIR
    chown -R $USER:$GROUP $DATA_DIR
    chown -R $USER:$GROUP $CONFIG_DIR
    
    chmod 755 $INSTALL_DIR
    chmod 750 $DATA_DIR
    chmod 750 $CONFIG_DIR
    chmod 755 $DATA_DIR/uploads
    
    log_success "Directories created and configured"
}

install_application() {
    log_info "Installing application files..."
    
    # Copy application files
    cp -r . $INSTALL_DIR/
    
    # Create Python virtual environment
    cd $INSTALL_DIR
    python3 -m venv venv
    source venv/bin/activate
    
    # Upgrade pip
    pip install --upgrade pip
    
    # Install Python dependencies
    pip install -r requirements.txt
    
    # Set ownership
    chown -R $USER:$GROUP $INSTALL_DIR
    
    # Make daemon script executable
    chmod +x $INSTALL_DIR/daemon.py
    
    log_success "Application installed"
}

configure_database() {
    log_info "Configuring MySQL database..."
    
    # Start MySQL service
    systemctl start mysql || systemctl start mysqld
    systemctl enable mysql || systemctl enable mysqld
    
    # Generate random password
    DB_PASSWORD=$(openssl rand -base64 32)
    
    # Create database and user
    mysql -u root <<EOF
CREATE DATABASE IF NOT EXISTS fixture_manager CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'fixture_user'@'localhost' IDENTIFIED BY '$DB_PASSWORD';
GRANT ALL PRIVILEGES ON fixture_manager.* TO 'fixture_user'@'localhost';
FLUSH PRIVILEGES;
EOF
    
    # Execute schema
    mysql -u fixture_user -p$DB_PASSWORD fixture_manager < $INSTALL_DIR/database/schema.sql
    
    # Save database credentials
    cat > $CONFIG_DIR/database.conf <<EOF
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=fixture_user
MYSQL_PASSWORD=$DB_PASSWORD
MYSQL_DATABASE=fixture_manager
EOF
    
    chmod 600 $CONFIG_DIR/database.conf
    chown $USER:$GROUP $CONFIG_DIR/database.conf
    
    log_success "Database configured"
}

create_config() {
    log_info "Creating configuration files..."
    
    # Generate secret keys
    SECRET_KEY=$(openssl rand -base64 32)
    JWT_SECRET_KEY=$(openssl rand -base64 32)
    
    # Create main configuration
    cat > $CONFIG_DIR/config.env <<EOF
# Database Configuration
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=fixture_user
MYSQL_PASSWORD=$(grep MYSQL_PASSWORD $CONFIG_DIR/database.conf | cut -d'=' -f2)
MYSQL_DATABASE=fixture_manager

# Security Configuration
SECRET_KEY=$SECRET_KEY
JWT_SECRET_KEY=$JWT_SECRET_KEY
BCRYPT_LOG_ROUNDS=12

# File Upload Configuration
UPLOAD_FOLDER=$DATA_DIR/uploads
MAX_CONTENT_LENGTH=524288000
CHUNK_SIZE=8192
MAX_CONCURRENT_UPLOADS=5

# Daemon Configuration
DAEMON_PID_FILE=/var/run/fixture-daemon.pid
DAEMON_LOG_FILE=$LOG_DIR/fixture-daemon.log
DAEMON_WORKING_DIR=$DATA_DIR

# Web Server Configuration
HOST=0.0.0.0
PORT=5000
DEBUG=false

# Logging Configuration
LOG_LEVEL=INFO

# JWT Configuration
JWT_ACCESS_TOKEN_EXPIRES=3600
EOF
    
    chmod 600 $CONFIG_DIR/config.env
    chown $USER:$GROUP $CONFIG_DIR/config.env
    
    # Create symlink for application
    ln -sf $CONFIG_DIR/config.env $INSTALL_DIR/.env
    
    log_success "Configuration files created"
}

create_systemd_service() {
    log_info "Creating systemd service..."
    
    cat > /etc/systemd/system/$SERVICE_NAME.service <<EOF
[Unit]
Description=Fixture Manager Daemon
After=network.target mysql.service
Requires=mysql.service

[Service]
Type=forking
User=$USER
Group=$GROUP
WorkingDirectory=$INSTALL_DIR
Environment=PATH=$INSTALL_DIR/venv/bin
ExecStart=$INSTALL_DIR/venv/bin/python $INSTALL_DIR/daemon.py start --config production
ExecStop=$INSTALL_DIR/venv/bin/python $INSTALL_DIR/daemon.py stop --config production
ExecReload=$INSTALL_DIR/venv/bin/python $INSTALL_DIR/daemon.py reload --config production
PIDFile=/var/run/fixture-daemon.pid
Restart=always
RestartSec=10

# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=$DATA_DIR $LOG_DIR /var/run

[Install]
WantedBy=multi-user.target
EOF
    
    # Reload systemd and enable service
    systemctl daemon-reload
    systemctl enable $SERVICE_NAME
    
    log_success "Systemd service created"
}

configure_nginx() {
    log_info "Configuring Nginx reverse proxy..."
    
    cat > /etc/nginx/sites-available/$PROJECT_NAME <<EOF
server {
    listen 80;
    server_name _;
    
    # Security headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
    
    # File upload size limit
    client_max_body_size 500M;
    
    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        
        # Timeout settings for large file uploads
        proxy_connect_timeout 300s;
        proxy_send_timeout 300s;
        proxy_read_timeout 300s;
    }
    
    # Static files (if any)
    location /static {
        alias $INSTALL_DIR/app/static;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # Health check endpoint
    location /health {
        proxy_pass http://127.0.0.1:5000/health;
        access_log off;
    }
}
EOF
    
    # Enable site
    ln -sf /etc/nginx/sites-available/$PROJECT_NAME /etc/nginx/sites-enabled/
    
    # Remove default site
    rm -f /etc/nginx/sites-enabled/default
    
    # Test and reload nginx
    nginx -t
    systemctl enable nginx
    systemctl restart nginx
    
    log_success "Nginx configured"
}

setup_logrotate() {
    log_info "Setting up log rotation..."
    
    cat > /etc/logrotate.d/$SERVICE_NAME <<EOF
$LOG_DIR/fixture-daemon.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 644 $USER $GROUP
    postrotate
        systemctl reload $SERVICE_NAME > /dev/null 2>&1 || true
    endscript
}
EOF
    
    log_success "Log rotation configured"
}

setup_firewall() {
    log_info "Configuring firewall..."
    
    if command -v ufw &> /dev/null; then
        # Ubuntu/Debian UFW
        ufw allow 22/tcp
        ufw allow 80/tcp
        ufw allow 443/tcp
        ufw --force enable
        log_success "UFW firewall configured"
    elif command -v firewall-cmd &> /dev/null; then
        # CentOS/RHEL firewalld
        firewall-cmd --permanent --add-service=ssh
        firewall-cmd --permanent --add-service=http
        firewall-cmd --permanent --add-service=https
        firewall-cmd --reload
        log_success "Firewalld configured"
    else
        log_warning "No firewall detected. Please configure manually."
    fi
}

create_backup_script() {
    log_info "Creating backup script..."
    
    cat > $INSTALL_DIR/backup.sh <<'EOF'
#!/bin/bash

# Fixture Manager Backup Script

BACKUP_DIR="/var/lib/fixture-daemon/backups"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="fixture_manager_backup_$DATE.tar.gz"

# Load database configuration
source /etc/fixture-manager/database.conf

# Create backup directory
mkdir -p $BACKUP_DIR

# Backup database
mysqldump -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE > $BACKUP_DIR/database_$DATE.sql

# Backup uploads
tar -czf $BACKUP_DIR/$BACKUP_FILE \
    --exclude='*.log' \
    --exclude='backups' \
    /var/lib/fixture-daemon/uploads \
    /etc/fixture-manager \
    $BACKUP_DIR/database_$DATE.sql

# Remove temporary database dump
rm $BACKUP_DIR/database_$DATE.sql

# Keep only last 7 backups
find $BACKUP_DIR -name "fixture_manager_backup_*.tar.gz" -mtime +7 -delete

echo "Backup completed: $BACKUP_DIR/$BACKUP_FILE"
EOF
    
    chmod +x $INSTALL_DIR/backup.sh
    chown $USER:$GROUP $INSTALL_DIR/backup.sh
    
    # Add to crontab for daily backups
    (crontab -u $USER -l 2>/dev/null; echo "0 2 * * * $INSTALL_DIR/backup.sh") | crontab -u $USER -
    
    log_success "Backup script created and scheduled"
}

start_services() {
    log_info "Starting services..."
    
    # Start and enable services
    systemctl start $SERVICE_NAME
    systemctl status $SERVICE_NAME --no-pager
    
    log_success "Services started"
}

print_summary() {
    log_success "Installation completed successfully!"
    echo
    echo "=== Installation Summary ==="
    echo "Application Directory: $INSTALL_DIR"
    echo "Data Directory: $DATA_DIR"
    echo "Configuration Directory: $CONFIG_DIR"
    echo "Log File: $LOG_DIR/fixture-daemon.log"
    echo "Service Name: $SERVICE_NAME"
    echo "User/Group: $USER:$GROUP"
    echo
    echo "=== Service Management ==="
    echo "Start service:   systemctl start $SERVICE_NAME"
    echo "Stop service:    systemctl stop $SERVICE_NAME"
    echo "Restart service: systemctl restart $SERVICE_NAME"
    echo "View logs:       journalctl -u $SERVICE_NAME -f"
    echo "View app logs:   tail -f $LOG_DIR/fixture-daemon.log"
    echo
    echo "=== Web Interface ==="
    echo "URL: http://$(hostname -I | awk '{print $1}')"
    echo "Default admin credentials:"
    echo "  Username: admin"
    echo "  Password: admin123"
    echo
    log_warning "IMPORTANT: Change the default admin password immediately!"
    echo
    echo "=== Configuration Files ==="
    echo "Main config: $CONFIG_DIR/config.env"
    echo "Database config: $CONFIG_DIR/database.conf"
    echo "Nginx config: /etc/nginx/sites-available/$PROJECT_NAME"
    echo
    echo "=== Backup ==="
    echo "Backup script: $INSTALL_DIR/backup.sh"
    echo "Backup directory: $DATA_DIR/backups"
    echo "Automatic daily backups at 2:00 AM"
}

# Main installation process
main() {
    log_info "Starting Fixture Manager installation..."
    
    check_root
    detect_os
    install_dependencies
    create_user
    create_directories
    install_application
    configure_database
    create_config
    create_systemd_service
    configure_nginx
    setup_logrotate
    setup_firewall
    create_backup_script
    start_services
    print_summary
}

# Run installation
main "$@"