#!/bin/sh
# Copyright (c) 2017 Markus Weippert
# GNU General Public License v3.0 (see https://www.gnu.org/licenses/gpl-3.0.txt)

PARAMS="
    backup/bool
    dest/str/r
    directory_mode/str
    force=thirsty/bool//true
    original_basename=_original_basename/str
    src/str
    validate/str
    $FILE_PARAMS
"
RESPONSE_VARS="src dest md5sum=md5sum_src checksum backup_file"

init() {
    md5sum_src=""
    checksum=""
    backup_file=""
}

main() {
    local tmp _IFS
    [ -e "$src" ] || fail "Source $src not found"
    [ -r "$src" ] || fail "Source $src not readable"
    [ ! -d "$src" ] || fail "Remote copy does not support recursive copy of directory: $src"

    checksum_src="$(dgst sha1 "$src")" || :
    md5sum_src="$(md5 "$src")"
    md5sum_dest=""

    [ -z "$original_basename" -o "${dest%/}" = "$dest" ] || {
        dest="$dest/$original_basename"
        tmp="$(dirname -- "$dest")"
        [ -d "$tmp" ] || {
            _IFS="$IFS"; IFS="/"; set -- $tmp; IFS="$_IFS"
            tmp="$mode"; mode="$directory_mode"
            local d
            local p=""
            for d; do
                [ -n "$d" ] || continue
                p="$p/$d"
                [ ! -d "$p" ] || continue
                try mkdir "$p"
                set_file_attributes "$p"
            done
            mode="$tmp"
        }
    }

    [ ! -d "$dest" ] || {
        dest="${dest%/}"
        [ -z "$original_basename" ] &&
            dest="$dest/$(basename -- "$src")" ||
            dest="$dest/$original_basename"
    }

    tmp="$(dirname -- "$dest")"
    [ -e "$dest" ] && {
        [ ! -h "$dest" -o -z "$follow" ] || dest="$(realpath "$dest")"
        [ -n "$force" ] || fail "file already exists"
        [ ! -r "$dest" ] || md5sum_dest="$(md5 "$dest")"
    } || [ -d "$tmp" ] || fail "Destination directory $tmp does not exist"
    [ -w "$tmp" ] || fail "Destination $tmp not writeable"

    [ "$md5sum_src" = "$md5sum_dest" -a ! -h "$dest" ] || {
        [ -n "$_ansible_check_mode" ] || {
            [ -z "$backup" ] || backup_file="$(backup_local "$dest")"
            [ ! -h "$dest" ] || { rm -f -- "$dest"; touch -- "$dest"; }
            [ -z "$validate" ] || {
                [ "${validate/%s/}" != "$validate" ] ||
                    fail "validate must contain %s: $validate"
                tmp="$($(printf "$validate" "$src") 2>&1)" ||
                    fail "failed to validate: $tmp"
            }
            try 'cat -- "$src" > "$dest"'
        }
        changed
    }

    [ -n "$_ansible_check_mode" ] || set_file_attributes "$dest"
}
