#!/bin/bash

# Configurações iniciais
printers=(
    "A2_Brother"
    "B10_Brother"
    "D2_Brother"
    "F9_Brother"
    "H302_Brother"
    "R1_Derac_Brother"
    "R2_Brother"
)

# Função para verificar e instalar dependências
check_and_install_dependencies() {
    local needs_install=()

    # Verifica se o curl está instalado
    if ! command -v curl &> /dev/null; then
        needs_install+=("curl")
    fi

    # Verifica se o smbclient está instalado
    if ! command -v smbclient &> /dev/null; then
        needs_install+=("smbclient")
    fi

    # Verifica se o cups está instalado e ativo
    if ! dpkg -l | grep -q "cups"; then
        needs_install+=("cups")
    fi

    # Se houver pacotes para instalar
    if [ ${#needs_install[@]} -gt 0 ]; then
        echo "Instalando dependências ausentes: ${needs_install[*]}..."
        apt-get update
        apt-get install -y "${needs_install[@]}"

        # Habilita e inicia o cups se foi instalado
        if [[ " ${needs_install[*]} " =~ " cups " ]]; then
            systemctl enable cups
            systemctl start cups
        fi
    else
        echo "Todas as dependências já estão instaladas."
    fi
}

# Função para verificar root
check_root() {
    if [ "$(id -u)" -ne 0 ]; then
        echo "Este script deve ser executado como root."
        exit 1
    fi
}

# Função para habilitar suporte a 32 bits
enable_32bit_support() {
    echo "Habilitando suporte a pacotes de 32 bits..."
    dpkg --add-architecture i386
    apt-get update
    apt-get install -y libc6:i386 lib32stdc++6 libncurses5:i386 libstdc++6:i386
}

# Função para baixar PPD alternativo
download_ppd() {
    echo "Baixando arquivo PPD alternativo..."
    curl -f -o /tmp/mfcl6702dw.ppd https://wiki.gp.utfpr.edu.br/arquivos/mfcl6702dw.ppd || {
        echo "Aviso: PPD alternativo não pôde ser baixado, usando o padrão do driver."
        return 1
    }
    return 0
}

# Função para instalar o driver Brother
install_brother_driver() {
    echo "Instalando drivers Brother MFCL6702DW (32 bits)..."

    # Baixa os pacotes
    echo "Baixando pacotes..."
    curl -f -L -o /tmp/mfcl6702dwlpr.deb https://wiki.gp.utfpr.edu.br/executaveis/mfcl6702dwlpr-3.5.1-1.i386.deb || {
        echo "Erro ao baixar LPR"; return 1
    }
    
    curl -f -L -o /tmp/mfcl6702dwcupswrapper.deb https://wiki.gp.utfpr.edu.br/executaveis/mfcl6702dwcupswrapper-3.5.1-1.i386.deb|| {
        echo "Erro ao baixar CUPS wrapper"; return 1
    }
    
    # Instala os pacotes
    echo "Instalando pacotes..."
    dpkg -i /tmp/mfcl6702dwlpr.deb /tmp/mfcl6702dwcupswrapper.deb || apt-get install -f -y
    
    # Verifica se a instalação foi bem sucedida
    if [ ! -f "/usr/lib/cups/filter/brother_lpdwrapper_MFCL6702DW" ]; then
        echo "ERRO: O filtro brother_lpdwrapper_MFCL6702DW não foi instalado corretamente."
        return 1
    fi
    
    echo "Driver Brother instalado com sucesso."
    return 0
}

# Função para remover a impressora padrão
remove_default_printer() {
    echo "Removendo impressora padrão MFCL6702DW..."
    lpadmin -x MFCL6702DW 2>/dev/null
    echo "Impressora padrão removida."
}

# Função para selecionar impressora
select_printer() {
    echo "Selecione a impressora para configurar:"
    for i in "${!printers[@]}"; do
        echo "$i: ${printers[$i]}"
    done

    while true; do
        read -p "Digite o número da impressora: " choice
        if [[ "${printers[$choice]}" ]]; then
            selected_printer="${printers[$choice]}"
            break
        else
            echo "Impressora inválida. Tente novamente."
        fi
    done
}

# Função para codificar URL (escapar caracteres especiais)
urlencode() {
    local string="${1}"
    local strlen=${#string}
    local encoded=""
    local pos c o

    for (( pos=0 ; pos<strlen ; pos++ )); do
        c=${string:$pos:1}
        case "$c" in
            [-_.~a-zA-Z0-9] ) 
                encoded+="${c}" 
                ;;
            @ ) 
                encoded+="%40" 
                ;;
            * ) 
                printf -v o '%%%02x' "'$c" 
                encoded+="${o}"
                ;;
        esac
    done
    echo -n "${encoded}"
}

# Função para configurar a impressora selecionada
configure_printer() {
    local printer=$1
    local username=$2
    local password=$3

    echo "Configurando impressora $printer..."

    # Remove a impressora se já existir
    lpadmin -x "$printer" 2>/dev/null

    # Verifica qual PPD usar
    if [ -f "/tmp/mfcl6702dw.ppd" ]; then
        ppd_path="/tmp/mfcl6702dw.ppd"
        echo "Usando PPD baixado..."
    else
        ppd_path="/opt/brother/Printers/mfcl6702dw/cupswrapper/brother_mfcl6702dw_printer_en.ppd"
        echo "Usando PPD do driver..."
    fi
    
    echo "Adicionando impressora: $printer"
    
    # Copia o PPD
    if [ -f "/tmp/mfcl6702dw.ppd" ]; then
        cp /tmp/mfcl6702dw.ppd /etc/cups/ppd/$printer.ppd
        chown root:lp /etc/cups/ppd/$printer.ppd
        chmod 640 /etc/cups/ppd/$printer.ppd
    fi

    # Testa a conexão SMB antes de configurar
    smbclient "//172.20.10.9/$printer" -U "$username%$password" -c "quit" &>/dev/null
    
    # Verifica se o backend smb está disponível
    if [ ! -f "/usr/lib/cups/backend/smb" ] && [ ! -f "/usr/libexec/cups/backend/smb" ]; then
        apt-get install -y cups-backends &>/dev/null || true
    fi
    
    # Para o CUPS SMB backend, precisamos usar um formato específico
    # Primeiro tenta com codificação URL
    encoded_username=$(urlencode "$username")
    encoded_password=$(urlencode "$password")
    
    # Cria a URI SMB com credenciais embutidas
    # Formato: smb://username:password@host/printer
    smb_address="smb://${encoded_username}:${encoded_password}@172.20.10.9/$printer"
    
    # Adiciona a impressora usando URI com credenciais
    if ! lpadmin -p "$printer" -v "$smb_address" -P "$ppd_path" -E -L "Brother MFCL6702DW - $printer" &>/dev/null; then
        # Tenta com formato smb://host/printer e configura credenciais separadamente
        smb_address_simple="smb://172.20.10.9/$printer"
        lpadmin -p "$printer" -v "$smb_address_simple" -P "$ppd_path" -E -L "Brother MFCL6702DW - $printer" &>/dev/null
        
        # Se ainda assim não funcionar, tenta novamente com a URI completa
        if ! lpstat -p "$printer" &>/dev/null; then
            lpadmin -x "$printer" &>/dev/null
            lpadmin -p "$printer" -v "$smb_address" -P "$ppd_path" -E -L "Brother MFCL6702DW - $printer" &>/dev/null
        fi
    fi
    
    # Aguarda um momento para o CUPS processar
    sleep 1
    
    # Verifica se a impressora foi criada corretamente
    if ! lpstat -p "$printer" &>/dev/null; then
        echo "ERRO: Falha ao criar a impressora."
        return 1
    fi
    
    # Define como impressora padrão
    lpoptions -d "$printer" &>/dev/null
    
    # Verifica e ajusta o arquivo printers.conf se necessário
    # Garante que a URI tenha as credenciais corretas
    if [ -f "/etc/cups/printers.conf" ]; then
        # Para o arquivo printers.conf, precisamos parar o CUPS primeiro
        systemctl stop cups
        
        # Se a URI não contém credenciais, adiciona manualmente
        if grep -q "^<Printer $printer>" /etc/cups/printers.conf; then
            current_uri=$(grep -A 10 "^<Printer $printer>" /etc/cups/printers.conf | grep "^DeviceURI" | head -1 | cut -d' ' -f2-)
            
            if [[ ! "$current_uri" =~ @ ]]; then
                # Faz backup
                cp /etc/cups/printers.conf /etc/cups/printers.conf.backup.$(date +%s)
                
                # Substitui a linha DeviceURI sem credenciais pela com credenciais
                sed -i "/^<Printer $printer>/,/^<\/Printer>/ {
                    s|^DeviceURI.*|DeviceURI $smb_address|
                }" /etc/cups/printers.conf
            fi
        fi
        
        # Reinicia o CUPS para aplicar as mudanças
        systemctl start cups
        sleep 2
    fi
    
    echo "Impressora $printer configurada com credenciais salvas."
}

# Função principal
main() {
    check_root
    
    # Verifica e instala dependências
    check_and_install_dependencies
    
    # Continua com a instalação
    enable_32bit_support
    download_ppd
    install_brother_driver
     
    # Remove a impressora padrão que vem com o driver
    remove_default_printer
    
    # Seleção e configuração da impressora desejada
    select_printer
    
    read -p "Digite seu nome de usuário do domínio (sem o @ad.gp.utfpr.edu.br): " username
    read -s -p "Digite sua senha do domínio: " password
    echo
    
    full_username="$username@ad.gp.utfpr.edu.br"
    
    configure_printer "$selected_printer" "$full_username" "$password"
    
    echo "Instalação concluída!"
}

main
exit 0
