#!/usr/bin/sh
#
# Copyright (C) 2025  Etersoft
# Copyright (C) 2025  Vitaly Lipatov <lav@etersoft.ru>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

load_helper epm-sh-search

# APT sources paths with test isolation support (EPM_APT_SOURCES_ROOT)
if [ -n "$EPM_APT_SOURCES_LIST" ] ; then
    APT_SOURCES_LIST="$EPM_APT_SOURCES_LIST"
    APT_SOURCES_LIST_D=''
    APT_ALL_SOURCES_LIST="$EPM_APT_SOURCES_LIST"
else
    APT_SOURCES_LIST="${EPM_APT_SOURCES_ROOT%/}/etc/apt/sources.list"
    APT_SOURCES_LIST_D="${EPM_APT_SOURCES_ROOT%/}/etc/apt/sources.list.d"
    APT_ALL_SOURCES_LIST="$APT_SOURCES_LIST_D/*.list $APT_SOURCES_LIST_D/*.sources $APT_SOURCES_LIST"
fi

# Convert deb822 .sources file to one-line deb format
__convert_deb822_to_oneline()
{
    local types="" uris="" suites="" components="" enabled=""
    while IFS= read -r line ; do
        case "$line" in
            Enabled:*) enabled="${line#Enabled: }" ;;
            Types:*) types="${line#Types: }" ;;
            URIs:*) uris="${line#URIs: }" ;;
            Suites:*) suites="${line#Suites: }" ;;
            Components:*) components="${line#Components: }" ;;
            ""|"#"*)
                if [ -n "$types" ] && [ -n "$uris" ] && [ -n "$suites" ] ; then
                    local prefix=""
                    [ "$enabled" = "no" ] && prefix="# "
                    local t u s
                    for t in $types ; do
                        for u in $uris ; do
                            for s in $suites ; do
                                echo "${prefix}${t} ${u} ${s} ${components}"
                            done
                        done
                    done
                fi
                types="" ; uris="" ; suites="" ; components="" ; enabled=""
                ;;
        esac
    done < "$1"
    # flush last block
    if [ -n "$types" ] && [ -n "$uris" ] && [ -n "$suites" ] ; then
        local prefix=""
        [ "$enabled" = "no" ] && prefix="# "
        local t u s
        for t in $types ; do
            for u in $uris ; do
                for s in $suites ; do
                    echo "${prefix}${t} ${u} ${s} ${components}"
                done
            done
        done
    fi
}

# Find .sources files matching pattern (by converted one-line content)
__find_deb822_files_by_pattern()
{
    local pattern="$1"
    local i
    for i in $APT_SOURCES_LIST_D/*.sources ; do
        test -r "$i" || continue
        __convert_deb822_to_oneline "$i" | grep -q -i -- "$pattern" && echo "$i"
    done
}

# Disable repos in a deb822 .sources file (set Enabled: no)
__deb822_disable()
{
    local file="$1"
    if grep -q "^Enabled:" "$file" ; then
        sudocmd sed -i -e 's/^Enabled:.*/Enabled: no/' "$file"
    else
        sudocmd sed -i -e '/^Types:/i Enabled: no' "$file"
    fi
}

# Enable repos in a deb822 .sources file (remove Enabled: no)
__deb822_enable()
{
    local file="$1"
    sudocmd sed -i -e '/^Enabled:[[:space:]]*no/d' "$file"
}

# Remove a deb822 .sources file
__deb822_remove()
{
    sudocmd rm -v "$1"
}

# Filter stdin by patterns (AND logic, case insensitive)
# Supports glob (* ?) and exclusion (~pattern)
# Usage: echo "$lines" | __filter_repos_list pattern1 pattern2 ~exclude
__filter_repos_list()
{
    local i pattern
    [ -z "$*" ] && cat && return

    # Check if this is a full repo line (rpm or deb) - use literal matching for the entire string
    if echo "$1" | grep -q '^rpm\|^deb' && [ $# -eq 1 ] ; then
        grep -F -i -- "$1"
        return
    fi

    local result
    result="$(cat)"

    # process each argument preserving spaces in patterns
    for i in "$@" ; do
        case "$i" in
            ~*)
                # exclusion pattern
                pattern="${i#\~}"
                [ -z "$regexp" ] && pattern=$(__epm_glob_to_regexp "$pattern")
                result="$(echo "$result" | grep -E -i -v -- "$pattern")"
                ;;
            *)
                # inclusion pattern (AND logic)
                pattern="$i"
                [ -z "$regexp" ] && pattern=$(__epm_glob_to_regexp "$pattern")
                result="$(echo "$result" | grep -E -i -- "$pattern")"
                ;;
        esac
    done

    [ -n "$result" ] && echo "$result"
}

# set enabled=<0|1> for dnf/yum repos in /etc/yum.repos.d
# args: <0|1> <name|repo id> ...
# name: all repos from /etc/yum.repos.d/<name>.repo or alt-<name>.repo
__epm_dnf_set_repo_enabled()
{
    local value="$1"
    shift
    local repo f ids found
    for repo in "$@" ; do
        found=''
        for f in /etc/yum.repos.d/*.repo ; do
            [ -e "$f" ] || continue
            if [ "$f" = "/etc/yum.repos.d/$repo.repo" ] || [ "$f" = "/etc/yum.repos.d/alt-$repo.repo" ] ; then
                ids="*"
            elif grep -q -F "[$repo]" "$f" ; then
                ids="$repo"
            else
                continue
            fi
            found=1
            local tmpfile
            tmpfile=$(mktemp) || fatal
            remove_on_exit $tmpfile
            awk -v ids="$ids" -v value="$value" '
                /^\[.*\]/ { insec = (ids == "*" || $0 == "[" ids "]"); print; if (insec) print "enabled=" value; next }
                insec && /^[[:space:]]*enabled[[:space:]]*=/ { next }
                { print }' "$f" >$tmpfile
            cmp -s $tmpfile "$f" && continue
            chmod 644 $tmpfile
            sudocmd cp $tmpfile "$f"
        done
        [ -n "$found" ] || warning 'Repo $repo is not found in /etc/yum.repos.d'
    done
    return 0
}
