#!/bin/bash

set -euo pipefail  # Enable strict error handling

readonly JAVA_VERSION="17.0.14+7"
readonly INSTANCE_NAME="perdachcraft_7.2"
readonly INSTANCE_URL="https://files.perdach.com/${INSTANCE_NAME}.zip"

# Global variables
OS=""
ARCH=""
APP_DIR=""
JAVA_DIR=""
ARCHIVE_URL=""

# Initialize platform-specific variables
init_variables() {
    case "$OS" in
        mac)
            APP_DIR="$HOME/Library/Application Support/FjordLauncher"
			JAVA_DIR="$APP_DIR/java/jdk-$JAVA_VERSION-jre"
            ;;
        *)  # linux, alpine-linux, etc.
            APP_DIR="$HOME/.var/app/org.unmojang.FjordLauncher/data/FjordLauncher"
			JAVA_DIR="$APP_DIR/java/jdk-$JAVA_VERSION-jre"
            ;;
    esac
}

# Logger functions
log_info() { echo "[INFO] $*"; }
log_error() { echo "[ERROR] $*" >&2; }
log_success() { echo "[SUCCESS] $*"; }

# Exit handler
cleanup() {
    if [ $? -ne 0 ]; then
        log_error "Установка прервана из-за ошибки."
    fi
}
trap cleanup EXIT

# Utility functions
can_use_as_dir() {
    [[ -d "$1" && -x "$1" ]]
}

check_arch_support() {
    local os=$1
    local arch=$2
    
    case "$os" in
        linux)
            case "$arch" in
                x64|x86|arm|ppc64|ppc64le|s390x|riscv64) return 0 ;;
                *) return 1 ;;
            esac
            ;;
        mac)
            case "$arch" in
                x64|aarch64) return 0 ;;
                *) return 1 ;;
            esac
            ;;
        windows)
            case "$arch" in
                x64|x86) return 0 ;;
                *) return 1 ;;
            esac
            ;;
        alpine-linux)
            case "$arch" in
                x64) return 0 ;;
                *) return 1 ;;
            esac
            ;;
        aix)
            case "$arch" in
                ppc64) return 0 ;;
                *) return 1 ;;
            esac
            ;;
        *)
            return 1
            ;;
    esac
}

detect_platform() {
    # Detect OS
    if [ -f /etc/alpine-release ]; then
        OS="alpine-linux"
    elif [ "$(uname -s)" = "Darwin" ]; then
        OS="mac"
    elif [ "$(uname -s)" = "Linux" ]; then
        OS="linux"
    elif [ "$(uname -s)" = "AIX" ]; then
        OS="aix"
    elif [[ "$OSTYPE" =~ ^(cygwin|msys|win32)$ ]]; then
        OS="windows"
    else
        if [ -f /etc/os-release ]; then
            . /etc/os-release
            OS="$NAME"
        else
            OS="$(uname -s)"
        fi
        log_error "Неподдерживаемая ОС: $OS"
        exit 1
    fi

    # Detect architecture
    local machine
    machine="$(uname -m)"
    case "$machine" in
        x86_64)  ARCH="x64" ;;
        i386|i686) ARCH="x86" ;;
        armv7l)  ARCH="arm" ;;
        aarch64) ARCH="aarch64" ;;
        ppc64)   ARCH="ppc64" ;;
        ppc64le) ARCH="ppc64le" ;;
        s390x)   ARCH="s390x" ;;
        riscv64) ARCH="riscv64" ;;
        *)
            log_error "Неподдерживаемая архитектура: $machine"
            exit 1
            ;;
    esac

    log_info "Определена ОС: $OS"
    log_info "Определена архитектура: $ARCH"
}

construct_archive_url() {
    if ! check_arch_support "$OS" "$ARCH"; then
        log_error "Java недоступна для $OS с архитектурой $ARCH"
        log_error "Пожалуйста, установите Java вручную."
        exit 1
    fi

    ARCHIVE_URL="https://api.adoptopenjdk.net/v3/binary/latest/17/ga/$OS/$ARCH/jre/hotspot/normal/adoptopenjdk?project=jdk"
    # log_info "URL для Java: $ARCHIVE_URL"
}

install_java() {
    local dir
    dir="$APP_DIR/java"


    if ! can_use_as_dir "$dir"; then
        log_info "Создаём директорию $dir..."
        mkdir -p "$dir"
    fi
    
    if can_use_as_dir "$JAVA_DIR/bin"; then
        log_info "Java уже установлена в $JAVA_DIR"
        return 0
    fi

    log_info "Загружаем и устанавливаем OpenJDK 17..."
    if ! curl -L "$ARCHIVE_URL" | gunzip | tar xf - --directory="$dir"; then
        log_error "Ошибка при установке Java"
        return 1
    fi

    # MacOS
    if can_use_as_dir "$JAVA_DIR/Contents/Home"; then
        mv "$JAVA_DIR"/Contents/Home/* "$JAVA_DIR"
        rm -rf "$JAVA_DIR/Contents"
    fi

    log_success "Java успешно установлена"
}

install_launcher_mac() {
    if ! command -v brew &>/dev/null; then
        log_error "Homebrew не обнаружен... Установите: https://github.com/Homebrew/brew/releases/latest"

		# ну нахер, пусть юзвери сами ставят
		#yes "" | INTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
    fi

install_launcher_mac() {
    if ! command -v brew &>/dev/null; then
        log_error "Homebrew не обнаружен... Установите: https://github.com/Homebrew/brew/releases/latest"
        return 1
    fi

    if ! brew tap | grep -q "hero-persson/homebrew-unmojang"; then
        log_info "Настраиваем репозитории Homebrew..."
        brew tap hero-persson/homebrew-unmojang
    else
        log_info "Репозиторий hero-persson/homebrew-unmojang уже установлен."
    fi

    if ! brew list --cask | grep -q "fjordlauncher"; then
        log_info "Устанавливаем Fjord Launcher..."
        HOMEBREW_NO_AUTO_UPDATE=1 brew install --cask fjordlauncher
    else
        log_info "Fjord Launcher уже установлен."
    fi
}
}

install_launcher_linux() {
    if ! command -v flatpak &>/dev/null; then
        log_error "Flatpak не обнаружен... Установите: https://flatpak.org/setup"
        exit 1
    fi

    local repos="flathub|https://flathub.org/repo/flathub.flatpakrepo
hero-persson|https://hero-persson.github.io/unmojang-flatpak/index.flatpakrepo"

    echo "$repos" | while IFS='|' read -r name url; do
        if ! flatpak remote-list | grep -q "^$name"; then
            log_info "Добавляем репозиторий $name..."
            flatpak remote-add --if-not-exists "$name" "$url" --user
            if [ "$name" = "flathub" ]; then
                log_info "Требуется перезагрузка для продолжения установки"
                exit 0
            fi
        fi
    done

    if ! flatpak list --user | grep -q "org.unmojang.FjordLauncher"; then
        log_info "Устанавливаем Fjord Launcher..."
        flatpak install --user hero-persson org.unmojang.FjordLauncher --noninteractive
    fi
}

configure_launcher() {
    local config_lines="AutomaticJavaDownload=false
AutomaticJavaSwitch=false
IgnoreJavaCompatibility=true
IgnoreJavaWizard=true
UserAskedAboutAutomaticJavaDownload=true
MissingAuthlibInjectorBehavior=0
JavaDir=java
JavaPath=$JAVA_DIR/bin/java"

    local cfg_file="$APP_DIR/fjordlauncher.cfg"
    mkdir -p "$(dirname "$cfg_file")"

    if [ ! -f "$cfg_file" ]; then
        echo "$config_lines" > "$cfg_file"
        return 0
    fi

    # Update existing config
    local temp_file
    temp_file="$(mktemp)"
    cp "$cfg_file" "$temp_file"

    echo "$config_lines" | while IFS='=' read -r key value; do
        key=$(echo "$key" | xargs)
        value=$(echo "$value" | xargs)
        if grep -q "^$key=" "$temp_file"; then
            sed -i.bak "s|^$key=.*|$key=$value|" "$temp_file"
        else
            echo "$key=$value" >> "$temp_file"
        fi
    done

    mv "$temp_file" "$cfg_file"
}

create_launcher() {
    case "$OS" in
        mac)
            local apps_dir="$HOME/Applications"
            mkdir -p "$apps_dir"
            
            cat > "$apps_dir/Perdachcraft.command" << EOF
#!/bin/bash
open -a 'Fjord Launcher' --args --launch $INSTANCE_NAME
EOF
            chmod +x "$apps_dir/Perdachcraft.command"
            ;;
        *)
            cat > "$HOME/Desktop/perdachcraft.desktop" << EOF
[Desktop Entry]
Type=Application
Name=perdachcraft
Terminal=false
Exec='/usr/bin/flatpak' 'run' '--branch=master' '--arch=x86_64' '--command=fjordlauncher' '--file-forwarding' 'org.unmojang.FjordLauncher' '--launch' '$INSTANCE_NAME' @@u %U @@
StartupNotify=true
Icon=$APP_DIR/instances/$INSTANCE_NAME/.minecraft/icon.png
Categories=Game;ActionGame;AdventureGame;Simulation;
Keywords=game;minecraft;mc;
X-Flatpak=org.unmojang.FjordLauncher
EOF
            chmod +x "$HOME/Desktop/perdachcraft.desktop"
            ;;
    esac
}

import_instance() {
    if can_use_as_dir "$APP_DIR/instances/$INSTANCE_NAME/libraries"; then
        log_info "Сборка уже установлена"
        return 0
    fi

    log_info "Загружаем сборку..."
    mkdir -p "$APP_DIR"
    if ! curl -L "$INSTANCE_URL" -o "$APP_DIR/${INSTANCE_NAME}.zip"; then
        log_error "Ошибка при загрузке сборки"
        return 1
    fi

    case "$OS" in
        mac)
            open -a 'Fjord Launcher' --args --import "$APP_DIR/${INSTANCE_NAME}.zip"
            ;;
        *)
            flatpak run org.unmojang.FjordLauncher --import "$APP_DIR/${INSTANCE_NAME}.zip"
            ;;
    esac
}

main() {
    log_info "Запуск установщика perdachcraft"
    
    detect_platform
    init_variables
    construct_archive_url

    case "$OS" in
        mac)
            install_launcher_mac
            ;;
        *)
            install_launcher_linux
            ;;
    esac

    install_java
    configure_launcher
    import_instance
    create_launcher

    log_success "Установка завершена!"
    log_info "Можете запускать пердачкрафт и веселиться!"
}

main "$@"
