#!/usr/bin/env bash

#  Created: 2023/10/01
#
#  Copyright (c) 2023-2023, Bruno Goncalves <biglinux.com.br>
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions
#  are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
#  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
#  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
#  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
#  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
#  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

showHelp() {
    echo "-----------------------------------------------------------"
    echo "|           Variable Editor Script                        |"
    echo "-----------------------------------------------------------"
    echo "| Usage:                                                  |"
    echo "| $0 add <filePath> <variableName> <valueToModify>        |"
    echo "| $0 remove <filePath> <variableName> <keyToRemove>       |"
    echo "| $0 show <filePath> <variableName>                       |"
    echo "| $0 help                                                 |"
    echo "-----------------------------------------------------------"
    echo "| Operations:                                             |"
    echo "| add:     Add or update a key and its value              |"
    echo "| remove:  Remove a key (and its value if present)        |"
    echo "| show:    Display current keys and values one per line   |"
    echo "| help:    Show this help message                         |"
    echo "-----------------------------------------------------------"
    echo "| Examples using /etc/default/grub:                       |"
    echo "| $0 add /etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT \"quiet splash\"  |"
    echo "| $0 remove /etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT \"quiet\"      |"
    echo "| $0 show /etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT                 |"
    echo "-----------------------------------------------------------"
}

extractMainKey() {
    local str="$1"
    local mainKey="$str"
    
    if [[ "$str" =~ ":" ]]; then
        mainKey="${str%%:*}"
    elif [[ "$str" =~ "=" ]]; then
        mainKey="${str%%=*}"
    fi
    echo "$mainKey"
}

keyExistsInArray() {
    local fullKey="$1"
    local mainKey="$(extractMainKey "$fullKey")"
    
    for item in "${currentValueArray[@]}"; do
        if [[ "$(extractMainKey "$item")" == "$mainKey" ]]; then
            echo "yes"
            return
        fi
    done
    echo "no"
}

operation="$1"
filePath="$2"
variableName="$3"
modification="$4"

line=$(grep "^$variableName=" "$filePath")
currentValue="${line#*=}"
currentValue="${currentValue%\"}"
currentValue="${currentValue#\"}"
IFS=' ' read -ra currentValueArray <<< "$currentValue"

if [[ "$operation" == "show" ]]; then
    for value in "${currentValueArray[@]}"; do
        echo "$value"
    done
    exit 0
fi

if [[ "$operation" == "add" ]]; then
    if [[ $(keyExistsInArray "$modification") == "no" ]]; then
        currentValueArray+=("$modification")
    else
        mainKey="$(extractMainKey "$modification")"
        for index in "${!currentValueArray[@]}"; do
            if [[ "$(extractMainKey "${currentValueArray[$index]}")" == "$mainKey" ]]; then
                currentValueArray[$index]="$modification"
                break
            fi
        done
    fi
fi

if [[ "$operation" == "remove" ]]; then
    mainKey="$(extractMainKey "$modification")"
    for index in "${!currentValueArray[@]}"; do
        if [[ "$(extractMainKey "${currentValueArray[$index]}")" == "$mainKey" ]]; then
            unset currentValueArray[$index]
            break
        fi
    done
fi

updatedValue="${currentValueArray[*]}"
sed -i "/^$variableName=/c\\$variableName=\"$updatedValue\"" "$filePath"
