#!/data/data/com.termux/files/usr/bin/bash
# ==============================================================================
# OmniVoice Installer for Termux (Google Pixel 6a / GrapheneOS)
# Arch: ARM64 (aarch64) | Model: k2-fsa/OmniVoice (0.6B)
# ==============================================================================

set -e

# Kolory do komunikatów
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m' # No Color

echo -e "${CYAN}${BOLD}"
echo "=============================================================="
echo "    🎙️  Instalator OmniVoice dla Termux (Pixel 6a / GrapheneOS)"
echo "=============================================================="
echo -e "${NC}"

# 1. Sprawdzenie czy skrypt działa w środowisku Termux
if [ -z "$PREFIX" ] || [ ! -d "/data/data/com.termux" ]; then
    echo -e "${RED}⚠️  Uwaga: Ten skrypt jest przeznaczony do uruchomienia bezpośrednio w aplikacji Termux na Androidzie.${NC}"
    echo "Docelowym środowiskiem jest Google Pixel 6a z GrapheneOS."
    read -r -p "Czy na pewno chcesz kontynuować? (t/N): " confirm
    if [[ ! "$confirm" =~ ^[tTyY] ]]; then
        echo -e "${RED}Przerwano instalację.${NC}"
        exit 1
    fi
fi

# 2. Blokada uśpienia (Wake lock)
if command -v termux-wake-lock &>/dev/null; then
    echo -e "${BLUE}🔒 Aktywuję termux-wake-lock (zapobiega uśpieniu CPU podczas instalacji)...${NC}"
    termux-wake-lock
fi

# 3. Informacja o uprawnieniach na GrapheneOS
echo -e "${YELLOW}ℹ️  Wskazówka dla GrapheneOS:${NC}"
echo "  1. Wyłącz optymalizację baterii dla Termux (Ustawienia -> Aplikacje -> Termux -> Bateria -> Bez ograniczeń / Unrestricted)."
echo "  2. Pixel 6a posiada 6 GB RAM, co wystarcza na model OmniVoice 0.6B (~2.5 GB w pamięci)."
echo ""

# 4. Aktualizacja pakietów i naprawa dpkg w Termux
echo -e "${GREEN}[1/6] Aktualizacja repozytoriów i naprawa stanu pakietów w Termux...${NC}"

# Jeśli dpkg został przerwany przez błąd symboli w ffmpeg/libplacebo, napraw stan dpkg
dpkg --configure -a 2>/dev/null || true

# Jeśli ffmpeg na hoście Termux ma problem z bibliotekami NDK (libplacebo.so), usuwamy go z hosta Termux
# (Wszystkie operacje audio i konwersje odbywają się w bezpiecznym kontenerze Debian w proot!)
if dpkg -s ffmpeg 2>/dev/null | grep -Eq "half-configured|unpacked"; then
    echo -e "${YELLOW}Wykryto uszkodzony pakiet ffmpeg/mpv na hoście Termux (brakujący symbol NDK). Usuwam z hosta...${NC}"
    dpkg --remove --force-remove-reinstreq mpv ffmpeg libplacebo 2>/dev/null || true
fi

apt-get --fix-broken install -y 2>/dev/null || true

# Aktualizacja repozytoriów i pakietów bazowych (w tym libc++ do nowszego NDK)
pkg update -y || true
pkg upgrade -y -o Dpkg::Options::="--force-confold" || true

# 5. Instalacja wymaganych pakietów na hoście Termux
# UWAGA: Na hoście Termux NIE potrzebujemy ffmpeg ani kompilacji Pythona!
# Wystarczy proot-distro i narzędzia do pobierania. Cały stos AI i ffmpeg działa w Debianie.
echo -e "${GREEN}[2/6] Instalacja bazowych narzędzi w Termux (proot-distro, narzędzia sieciowe)...${NC}"
pkg install -y proot-distro curl wget git jq termux-tools

# Opcjonalnie próbujemy zainstalować odtwarzacz audio (jeśli repozytorium Termux pozwala), ale bez blokowania
pkg install -y termux-api 2>/dev/null || true

# 6. Przygotowanie kontenera proot-distro Debian
# Dlaczego Debian w proot?
# PyTorch nie posiada oficjalnych kółek (wheels) pod Android bionic libc (standardowy Termux).
# W proot-distro z Debianem mamy pełny glibc pod ARM64 (aarch64), co pozwala zainstalować
# oficjalny prekompilowany PyTorch CPU bez wielogodzinnej i niestabilnej kompilacji!
echo -e "${GREEN}[3/6] Konfiguracja środowiska Debian w proot-distro...${NC}"
if proot-distro list | grep -q "debian.*\[installed\]"; then
    echo -e "${BLUE}  Debian jest już zainstalowany w proot-distro. Pomijam pobieranie obrazu.${NC}"
else
    echo -e "${CYAN}  Pobieram i instaluję rootfs Debian...${NC}"
    proot-distro install debian
fi

# 7. Instalacja zależności i OmniVoice wewnątrz Debiana
echo -e "${GREEN}[4/6] Konfiguracja Pythona, PyTorch i OmniVoice wewnątrz Debiana...${NC}"

# Skrypt instalacyjny wykonywany wewnątrz Debiana
# shellcheck disable=SC2016
proot-distro login debian -- bash -c '
set -e

export DEBIAN_FRONTEND=noninteractive

echo "==> Aktualizacja pakietów Debiana..."
apt-get update -y
apt-get install -y --no-install-recommends \
    python3 \
    python3-pip \
    python3-venv \
    python3-dev \
    build-essential \
    ffmpeg \
    libsndfile1 \
    git \
    curl \
    wget \
    ca-certificates \
    sox \
    libsox-fmt-all \
    libopenblas0 \
    procps

# Tworzenie katalogu projektu i venv
OMNIDIR="/opt/omnivoice"
mkdir -p "$OMNIDIR/cache"
mkdir -p "$OMNIDIR/outputs"
mkdir -p "$OMNIDIR/references"

if [ ! -d "$OMNIDIR/venv" ]; then
    echo "==> Tworzenie środowiska wirtualnego Python w $OMNIDIR/venv..."
    python3 -m venv "$OMNIDIR/venv"
fi

echo "==> Aktywacja wirtualnego środowiska i aktualizacja pip..."
source "$OMNIDIR/venv/bin/activate"
pip install --upgrade pip setuptools wheel

# Instalacja oficjalnego PyTorch CPU pod aarch64 (Linux glibc)
echo "==> Instalacja PyTorch i TorchAudio (CPU dla ARM64)..."
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cpu

# Instalacja zależności pomocniczych
echo "==> Instalacja bibliotek audio, transformers i gradio..."
pip install "transformers>=4.45.0" accelerate pydub gradio soundfile librosa numpy num2words

# Instalacja k2-fsa/OmniVoice
echo "==> Instalacja biblioteki OmniVoice (k2-fsa)..."
pip install omnivoice || pip install git+https://github.com/k2-fsa/OmniVoice.git

# Utworzenie skryptu optymalizacyjnego dla Tensor G1 (ograniczenie liczby wątków do 4 dla stabilności RAM i zbalansowania rdzeni X1/A76)
cat << "EOF_INNER" > /opt/omnivoice/run_infer.py
import os
import sys
import torch

# Optymalizacja dla Pixel 6a (Tensor G1: 2x Cortex-X1 + 2x A76 + 4x A55)
# Ograniczamy do 4 wątków aby nie zapychać RAMu i nie throttlować małych rdzeni
torch.set_num_threads(4)
os.environ["OMP_NUM_THREADS"] = "4"
os.environ["MALLOC_ARENA_MAX"] = "2"

from omnivoice.cli.infer import get_parser, main

if __name__ == "__main__":
    main()
EOF_INNER

chmod +x /opt/omnivoice/run_infer.py
echo "==> Zakończono konfigurację wewnątrz Debiana!"
'

# 8. Tworzenie skrótów i wrapperów w Termux ($PREFIX/bin)
echo -e "${GREEN}[5/6] Tworzenie komend w Termux...${NC}"

# 8.1. omnivoice-infer
cat << 'EOF' > "$PREFIX/bin/omnivoice-infer"
#!/data/data/com.termux/files/usr/bin/bash
# Wrapper dla OmniVoice CLI
proot-distro login debian --bind /data/data/com.termux/files/home:/root/termux-home -- bash -c '
    export OMP_NUM_THREADS=4
    export TORCH_NUM_THREADS=4
    export HF_HOME=/opt/omnivoice/cache
    source /opt/omnivoice/venv/bin/activate
    python3 /opt/omnivoice/run_infer.py "$@"
' -- "$@"
EOF
chmod +x "$PREFIX/bin/omnivoice-infer"

# 8.2. omnivoice-demo (Gradio Web UI)
cat << 'EOF' > "$PREFIX/bin/omnivoice-demo"
#!/data/data/com.termux/files/usr/bin/bash
# Uruchamia interfejs webowy OmniVoice na http://127.0.0.1:7860
echo "🎙️ Uruchamiam OmniVoice Web UI..."
echo "📱 Po załadowaniu otwórz w przeglądarce: http://127.0.0.1:7860"
echo "Naciśnij Ctrl+C aby zatrzymać."
proot-distro login debian --bind /data/data/com.termux/files/home:/root/termux-home -- bash -c '
    export OMP_NUM_THREADS=4
    export TORCH_NUM_THREADS=4
    export HF_HOME=/opt/omnivoice/cache
    source /opt/omnivoice/venv/bin/activate
    omnivoice-demo --server-name 127.0.0.1 --server-port 7860
'
EOF
chmod +x "$PREFIX/bin/omnivoice-demo"

# 8.3. omnivoice-say (Szybka synteza i natychmiastowe odtworzenie)
cat << 'EOF' > "$PREFIX/bin/omnivoice-say"
#!/data/data/com.termux/files/usr/bin/bash
# Użycie: omnivoice-say "Tekst do przeczytania" [opcjonalny_plik_ref.wav] [tekst_referencji]
if [ -z "$1" ]; then
    echo "Użycie: omnivoice-say \"Tekst do przeczytania\" [ścieżka_do_audio_ref.wav] [tekst_audio_ref]"
    exit 1
fi

TEXT="$1"
REF_AUDIO="$2"
REF_TEXT="$3"
OUT_WAV="/data/data/com.termux/files/home/omnivoice_output.wav"

echo "⏳ Generuję mowę: \"$TEXT\"..."

EXTRA_ARGS=""
if [ -n "$REF_AUDIO" ] && [ -f "$REF_AUDIO" ]; then
    EXTRA_ARGS="--ref_audio /root/termux-home/$(basename "$REF_AUDIO")"
    if [ -n "$REF_TEXT" ]; then
        EXTRA_ARGS="$EXTRA_ARGS --ref_text \"$REF_TEXT\""
    fi
    cp "$REF_AUDIO" "$HOME/$(basename "$REF_AUDIO")"
fi

proot-distro login debian --bind /data/data/com.termux/files/home:/root/termux-home -- bash -c "
    export OMP_NUM_THREADS=4
    export TORCH_NUM_THREADS=4
    export HF_HOME=/opt/omnivoice/cache
    source /opt/omnivoice/venv/bin/activate
    python3 /opt/omnivoice/run_infer.py --text \"$TEXT\" --output /root/termux-home/omnivoice_output.wav $EXTRA_ARGS
"

if [ -f "$OUT_WAV" ]; then
    echo "🔊 Odtwarzanie audio..."
    if command -v mpv &>/dev/null && mpv --version &>/dev/null; then
        mpv --no-video "$OUT_WAV"
    elif command -v termux-media-player &>/dev/null; then
        termux-media-player play "$OUT_WAV"
    elif command -v termux-open &>/dev/null; then
        termux-open "$OUT_WAV"
    else
        echo "✅ Zapisano plik audio: $OUT_WAV"
    fi
else
    echo "❌ Błąd: Nie wygenerowano pliku audio."
fi
EOF
chmod +x "$PREFIX/bin/omnivoice-say"

# 8.4. omnivoice (Główne menu pomocnicze)
cat << 'EOF' > "$PREFIX/bin/omnivoice"
#!/data/data/com.termux/files/usr/bin/bash
clear
echo "=============================================================="
echo "          🎙️  OmniVoice — Pixel 6a (GrapheneOS)"
echo "=============================================================="
echo "Dostępne polecenia w Termux:"
echo ""
echo "  1) omnivoice-say \"Cześć, jak się masz?\""
echo "     -> Szybka synteza tekstu i automatyczne odtworzenie audio"
echo ""
echo "  2) omnivoice-demo"
echo "     -> Uruchomienie Web UI (Gradio) na http://127.0.0.1:7860"
echo ""
echo "  3) omnivoice-infer --text \"...\" --output wynik.wav"
echo "     -> Pełny interfejs CLI z opcjami klonowania głosu"
echo ""
echo "  4) Wejście do środowiska Debian:"
echo "     proot-distro login debian"
echo "=============================================================="
EOF
chmod +x "$PREFIX/bin/omnivoice"

# 9. Podsumowanie
echo -e "${GREEN}[6/6] Gotowe!${NC}"
echo ""
echo -e "${CYAN}${BOLD}Instalacja zakończona sukcesem!${NC}"
echo ""
echo "Możesz teraz przetestować syntezę poleceniem:"
echo -e "  ${YELLOW}omnivoice-say \"Cześć! OmniVoice działa pomyślnie na Pixel 6a z GrapheneOS.\"${NC}"
echo ""
echo "Lub uruchomić interfejs graficzny w przeglądarce:"
echo -e "  ${YELLOW}omnivoice-demo${NC} (otwórz http://127.0.0.1:7860)"
echo ""
