# @yaml
# signature: "edit <start>:<end>\n<replacement_text>\nend_of_edit"
# docstring: |
#   Replaces lines within the specified range (start, end] with the given text in the currently open file.
#   Usage: edit <start_line>:<end_line>
#   - <start_line>: The line number BEFORE the replacement is inserted (exclusive).
#   - <end_line>: The line number where the replacement ends (inclusive).
#   The replacement text should be provided immediately after the line numbers and terminated by a line containing only 'end_of_edit'.
#   Ensure proper indentation in the replacement text. For Python files, syntax errors will be checked, and the edit won't be executed if detected.
#   If an error occurs, review the error message and adjust the edit command accordingly. Reissuing the same command without modifications will result in the same error.
# end_name: end_of_edit
edit() {
    if [ -z "$CURRENT_FILE" ]
    then
        echo 'No file open. Use the `open` command first.'
        return
    fi

    local start_line="$(echo $1: | cut -d: -f1)"
    local end_line="$(echo $1: | cut -d: -f2)"

    if [ -z "$start_line" ] || [ -z "$end_line" ]
    then
        echo "Usage: edit <start_line>:<end_line>"
        return
    fi

    local re='^[0-9]+$'
    if ! [[ $start_line =~ $re ]]; then
        echo "Usage: edit <start_line>:<end_line>"
        echo "Error: start_line must be a number"
        return
    fi
    if ! [[ $end_line =~ $re ]]; then
        echo "Usage: edit <start_line>:<end_line>"
        echo "Error: end_line must be a number"
        return
    fi

    # Bash array starts at 0, so let's adjust
    local start_line=$((start_line))
    local end_line=$((end_line))

    local replacement=()
    while IFS= read -r line
    do
        replacement+=("$line")
    done

    # Create a backup of the current file
    cp "$CURRENT_FILE" "/root/$(basename "$CURRENT_FILE")_backup"

    # Read the file line by line into an array
    mapfile -t lines < "$CURRENT_FILE"
    local new_lines=("${lines[@]:0:$start_line}" "${replacement[@]}" "${lines[@]:$((end_line))}")
    # Write the new stuff directly back into the original file
    printf "%s\n" "${new_lines[@]}" >| "$CURRENT_FILE"
    
    # Run linter
    if [[ $CURRENT_FILE == *.py ]]; then
        lint_output=$(flake8 --select=F821,F822,F831,E111,E112,E113,E999,E902 "$CURRENT_FILE" 2>&1)
    else
        # do nothing
        lint_output=""
    fi

    # if there is no output, then the file is good
    if [ -z "$lint_output" ]; then
        export CURRENT_LINE=$start_line
        _constrain_line
        _print

        echo "File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary."
    else
        echo "ERROR: $lint_output"
        echo "Therefore this command has not been executed. The file has not been modified, please try again."

        # Restoring CURRENT_FILE to original contents.
        cp "/root/$(basename "$CURRENT_FILE")_backup" "$CURRENT_FILE"
    fi

    # Remove backup file
    rm -f "/root/$(basename "$CURRENT_FILE")_backup"
}
