#!/bin/bash
#
# BloquearApostas.app - executavel do bundle
# ------------------------------------------
# Equivalente macOS do BloquearApostas.exe: o usuario da dois cliques e
# nunca precisa abrir o Terminal.
#
# Num .app o executavel pode ser um script, mas o duplo clique NAO abre
# terminal nenhum - nao ha stdin nem stdout visiveis. Por isso toda a
# interface (menu, senha de administrador, resultado) e feita com dialogos
# nativos via osascript.
#
# A senha de administrador e pedida pelo proprio macOS, atraves de
# "do shell script ... with administrator privileges". Este script nunca
# ve nem manipula a senha.

set -uo pipefail

APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
RESOURCES_DIR="$APP_DIR/Contents/Resources"
TITLE="Bloquear Apostas"

# --- localizar o script e as listas -----------------------------------------
# 1) Bundle autocontido (gerado por build_app.sh): tudo dentro do .app
# 2) Dentro do repositorio: o .app fica em macos/, ao lado do script
if [[ -f "$RESOURCES_DIR/block_betting_sites.sh" ]]; then
    SCRIPT_PATH="$RESOURCES_DIR/block_betting_sites.sh"
    DATA_DIR="$RESOURCES_DIR/data"
else
    SCRIPT_PATH="$(cd "$APP_DIR/.." && pwd)/block_betting_sites.sh"
    DATA_DIR="$(cd "$APP_DIR/../.." && pwd)/data"
fi

# --- helpers de dialogo -----------------------------------------------------
# Escapa aspas e barras invertidas para interpolar com seguranca em AppleScript.
as_quote() {
    printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g'
}

show_message() {
    local text icon
    text="$(as_quote "$1")"
    icon="${2:-note}"
    osascript -e "display dialog \"$text\" with title \"$(as_quote "$TITLE")\" buttons {\"OK\"} default button \"OK\" with icon $icon" >/dev/null 2>&1
}

fail() {
    show_message "$1" stop
    exit 1
}

# --- verificacoes -----------------------------------------------------------
if [[ ! -f "$SCRIPT_PATH" ]]; then
    fail "Nao encontrei o script de bloqueio.

Esperado em:
$SCRIPT_PATH

Se voce moveu o app para fora da pasta do projeto, gere uma versao autocontida rodando build_app.sh."
fi

if [[ ! -f "$DATA_DIR/sites.txt" || ! -f "$DATA_DIR/terms.txt" ]]; then
    fail "Nao encontrei as listas de sites e termos.

Esperado em:
$DATA_DIR"
fi

# --- menu -------------------------------------------------------------------
# Sem o caractere de continuacao "not sign" do AppleScript: ele depende do
# encoding com que o osascript le o script, e uma linha longa nao depende.
CHOICE=$(osascript <<APPLESCRIPT 2>/dev/null
set opcoes to {"Ativar o bloqueio", "Ver a situacao atual", "Desativar o bloqueio"}
set escolha to choose from list opcoes with title "$(as_quote "$TITLE")" with prompt "Bloqueador de sites de apostas" & return & return & "O que voce quer fazer?" default items {"Ativar o bloqueio"} OK button name "Continuar" cancel button name "Sair"
if escolha is false then
    return "cancelado"
else
    return item 1 of escolha
end if
APPLESCRIPT
)

case "$CHOICE" in
    "Ativar o bloqueio")     ACTION="enable"  ;;
    "Ver a situacao atual")  ACTION="status"  ;;
    "Desativar o bloqueio")  ACTION="disable" ;;
    *) exit 0 ;;
esac

# --- executar com privilegio de administrador -------------------------------
# O macOS mostra o proprio dialogo de senha; a senha nao passa por aqui.
COMMAND="BETTING_BLOCKER_DATA_DIR=$(printf '%q' "$DATA_DIR") /bin/bash $(printf '%q' "$SCRIPT_PATH") $ACTION 2>&1"

OUTPUT=$(osascript -e "do shell script \"$(as_quote "$COMMAND")\" with administrator privileges" 2>&1)
STATUS=$?

if [[ $STATUS -ne 0 ]]; then
    if [[ "$OUTPUT" == *"User canceled"* || "$OUTPUT" == *"-128"* ]]; then
        exit 0
    fi
    fail "O bloqueio nao pode ser concluido.

$OUTPUT"
fi

# --- resultado --------------------------------------------------------------
if [[ "$ACTION" == "status" ]]; then
    show_message "$OUTPUT"
    exit 0
fi

show_message "$OUTPUT

As listas ficam em:
$DATA_DIR

Edite esses arquivos para incluir ou remover sites e rode este app de novo."

# --- fechar os navegadores --------------------------------------------------
# As politicas de bloqueio so sao lidas quando o navegador inicia, entao um
# navegador aberto continua navegando sem bloqueio nenhum.
BROWSERS=("Google Chrome" "Microsoft Edge" "Brave Browser" "Firefox" "Safari" "Opera" "Vivaldi")
RUNNING=()
for browser in "${BROWSERS[@]}"; do
    if pgrep -x "$browser" >/dev/null 2>&1; then
        RUNNING+=("$browser")
    fi
done

if [[ ${#RUNNING[@]} -eq 0 ]]; then
    exit 0
fi

LIST=$(printf '%s\n' "${RUNNING[@]}")
ANSWER=$(osascript -e "display dialog \"O bloqueio so passa a valer num navegador reiniciado.

Estao abertos agora:
$(as_quote "$LIST")

Vou pedir para eles fecharem normalmente, salvando a sessao. Ao reabrir, o navegador costuma oferecer restaurar as abas.\" with title \"$(as_quote "$TITLE")\" buttons {\"Agora nao\", \"Fechar navegadores\"} default button \"Fechar navegadores\" with icon caution" 2>&1)

if [[ "$ANSWER" != *"Fechar navegadores"* ]]; then
    exit 0
fi

for browser in "${RUNNING[@]}"; do
    # Pedido educado: o app salva a sessao e encerra sozinho.
    osascript -e "tell application \"$(as_quote "$browser")\" to quit" >/dev/null 2>&1 || true
done

# Da tempo de salvarem a sessao antes de insistir.
for _ in $(seq 1 20); do
    still_running=0
    for browser in "${RUNNING[@]}"; do
        pgrep -x "$browser" >/dev/null 2>&1 && still_running=1
    done
    [[ $still_running -eq 0 ]] && break
    sleep 0.5
done

# O que resistiu vai a forca.
KILLED=0
for browser in "${RUNNING[@]}"; do
    if pgrep -x "$browser" >/dev/null 2>&1; then
        pkill -x "$browser" >/dev/null 2>&1 && KILLED=1
    fi
done

if [[ $KILLED -eq 1 ]]; then
    show_message "Alguns navegadores precisaram ser encerrados a forca.

Pode abrir o navegador de novo: o bloqueio ja estara valendo."
else
    show_message "Navegadores fechados.

Pode abrir de novo: o bloqueio ja estara valendo."
fi
