#!/bin/bash

## Copyright (C) 2024 - 2024 ENCRYPTED SUPPORT LP <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

## Usage:
## append-once /path/to/file 'line to append'

## TODO: Does not support multi-line (with empty lines) yet.

#set -x
set -e
set -o errtrace
set -o pipefail
set -o nounset

true "$0: INFO: START"

error_handler() {
  echo "$0: ERROR: An error occurred" >&2
  exit 1
}

trap error_handler ERR

append_once() {
  local file_name="$1"
  local line="$2"

  if ! test -f "$file_name" ; then
    true "INFO: File does not exist yet: $file_name"
    local dir_name
    ## Pure bash would be preferred over external `dirname` command. (Simplifies mandatory access control.)
    ## But pure bash does not handle cases where simply a file name is given without a directory.
    #dir_name="${file_name%/*}"
    dir_name="$(dirname -- "$file_name")"
    if ! test -w "$dir_name" ; then
      echo "$0: ERROR: Folder '$dir_name' (where file '$file_name' should be created) is not writeable!" >&2
      exit 1
    fi
  else
    if ! test -r "$file_name" ; then
      echo "$0: ERROR: File '$file_name' not readable!" >&2
      exit 1
    fi
    if str_match "$line" "$file_name" 2>/dev/null ; then
      true "INFO: Line already exists in: $file_name"
      return 0
    fi
    if ! test -w "$file_name" ; then
      echo "$0: ERROR: File '$file_name' not writeable!" >&2
      exit 1
    fi
  fi

  true "INFO: Appending line to: $file_name"
  ## Use `sponge`, because it is atomic, for nicer xtrace and better error handling.
  echo "$line" | sponge -a -- "$file_name"
}

# Main execution
if [ $# -ne 2 ]; then
  echo "Usage: $0 /path/to/file 'line to append'" >&2
  exit 1
fi

file_path="$1"
line_to_append="$2"

append_once "$file_path" "$line_to_append"

true "$0: INFO: END"
