#!/usr/bin/expect -f

if {![exp_debug]} {trap {exit 1} {SIGINT SIGTERM}}

variable noconfirm [string equal $::env(AUTOPACMAN_PACMAN_NOCONFIRM) "1"]
variable noconfirm_downloading false
variable conflictsfile_set [expr [info exist ::env(AUTOPACMAN_CONFLICTSFILE)] && [file exist $::env(AUTOPACMAN_CONFLICTSFILE)] ? true : false]

# [package to be replaced]: [package to be replaced with]
array set auto_replace_conflicts {
    python-xdg python-pyxdg
    vimix-gtk-themes snigdhaos-vimix-dark
    bibata-cursor-theme sweet-theme-full-git
    kvantum-theme-sweet-git sweet-theme-full-git
    sweet-gtk-theme-dark sweet-theme-full-git
    plasma5-theme-sweet-git sweet-theme-full-git
    xcursor-sweet sweet-theme-full-git
    exe-thumbnailer icoextract
    pipewire-media-session wireplumber
    qemu-base qemu-desktop
    libretro-mame-git libretro-meta
    jack2 pipewire-jack
    networkmanager-fortisslvpn networkmanager-support
    ananicy-rules cachyos-ananicy-rules-git
    sweet-theme-full-git plasma5-themes-sweet-full-git
    sweet-kde-theme-git plasma5-themes-sweet-kde-git
    jre-openjdk jdk-openjdk
    jre-openjdk-headless {jdk-openjdk jre-openjdk}
}

if { $::conflictsfile_set } {
    set conflictsfile [open $::env(AUTOPACMAN_CONFLICTSFILE) r]
    array set auto_replace_conflicts [gets $conflictsfile]
    close $conflictsfile
}

proc parseConflicts {first second} {
    foreach {key value} [array get ::auto_replace_conflicts] {
        if { [string equal $second $key] && [lsearch -exact $value $first] != -1 } {
            send "y\r"
            return
        }
    }
    if { $::noconfirm } {
        return
    } elseif { $::conflictsfile_set } {
        send "n\r"
    } else {
        expect_user -timeout -1 -re "(.*)\n"
        if {[regexp {^[Yy]$} $expect_out(1,string)]} {
            set ::auto_replace_conflicts($second) $first
            send "y\r"
        } else {
            send "n\r"
        }
    }
}

proc doExit {} {
    catch wait result
    if {[info exist ::env(AUTOPACMAN_CONFLICTSFILE)] && ![file exist $::env(AUTOPACMAN_CONFLICTSFILE)] } {
        set conflictsfile [open $::env(AUTOPACMAN_CONFLICTSFILE) [list WRONLY CREAT EXCL] 0600]
        puts $conflictsfile [array get ::auto_replace_conflicts]
        close $conflictsfile
    }
    exit [lindex $result 3]
}

spawn {*}$argv

log_user 1

set timeout -1

expect {
    "Starting full system upgrade..." { }
    eof doExit
}

set timeout 15

expect {
    -re {Replace \S+ with \S+ \[Y\/n\]} { send "y\r"; exp_continue }
    "resolving dependencies..." { }
    timeout { }
    eof doExit
}

expect {
    "looking for conflicting packages" { exp_continue }
    "Enter a number (default=1):" { if { $noconfirm } { send "1\r"; exp_continue; } { interact -o "\r" exp_continue; } }
    -re {(\S+) and (\S+) are in conflict( \(\S+\))?\.} { parseConflicts $expect_out(1,string) $expect_out(2,string); exp_continue }
    -re {Proceed with installation.*} { if { [info exist ::env(AUTOPACMAN_LOG)] } { log_file $::env(AUTOPACMAN_LOG) }; if { $::noconfirm || $::conflictsfile_set } { send "y\r"; set noconfirm_downloading true } }
    timeout { }
    eof doExit
}

if { $noconfirm } {
    if { $noconfirm_downloading } {
        set timeout -1
        expect {
            -re {Do you want to delete it.*} { send "y\r"; exp_continue }
            -re {.*\[Y/n\]} { }
            eof doExit
        }
    }
    exp_send_error "\nUnexpected user input required. Try again without --noconfirm"
    close
} else {
    expect_background {
        -re {Do you want to delete it.*} { send "y\r"; exp_continue }
    }
    catch interact
}
doExit
