#!/bin/bash

# DiskStation - Cloud Sync - Conflict Resolver
# 
# This script recursively searches a directory for duplicate files 
# matching $CONFLICTSTR ('conflict string'), as created by the Cloud 
# Sync app for Synology DiskStations. Whenever Cloud Sync finds a 
# conflict, it creates a new files and inserts '_DiskStation_..._Conflict' 
# just before the file extension. This script will detect such duplicates,
# move the file with the original name to $BACKUPDIR, and then strip the
# $CONFLICTSTR from the duplicate created by Cloud Sync. Note that this
# script could be used for similar tasks by adjusting the default values
# of these variables, but it was only designed to work for the conflict
# scenario at United Way in July, 2020. 
#
# Usage: ./ds_cs_conflict.sh [search_dir] [ | tee ./logfile]
#
# You may use the optional "search_dir" argument to specify the directory
# to search for conflicting files. The [ | tee ./logfile] is just to
# demonstrate one way to log output to a file (for users unfamiliar with 
# Unix systems).
#
# Author: Tyler Melton
# Email: tyler@tylerweb.net
# Created: 07/29/2020
# Modified: 07/30/2020


## Settings ##

# Regex signature for identifying a conflicting file
CONFLICTSTR='_DiskStation.*_Conflict'

# Directory in which to store conflicting files with original names
BACKUPDIR='./conflict_backups'

# Directory to search. If not provided as the first argument, use pwd
if [[ $# -eq 0 ]]; then
    echo ""
    echo "No path specified. Using current directory..."
    SEARCHDIR=`pwd`
elif [[ ! -d "$1" ]]; then
    error_exit "The path provided is not a directory: $1"
else 
    SEARCHDIR="$1"
fi



## Helpers ##

function error_exit {
    echo ""
    echo "$1 Exiting..."
    echo ""
    exit -1
}


## Main Routine ##
echo ""
echo "Preparing to resolve conflicting files..."

# Change to working directory
cd "$SEARCHDIR" || error_exit "Failed to change to the search directory: $SEARCHDIR"

# Create backup directory, if it doesn't exist
if [ ! -d "$BACKUPDIR" ]; then
    echo "Backup directory $BACKUPDIR does not exist. Creating..."
    mkdir "$BACKUPDIR" || error_exit "Failed to create backup directory."
else 
    echo "Backup directory $BACKUPDIR exists. Continuing on..."
fi

# Iterate over files, fixing conflicts if one is detected
echo ""
echo "Beginning file analysis..."
while IFS= read -r -d $'\0' f; do
    if [[ $f =~ $CONFLICTSTR ]]; then

        # Strip off leading './'
        f=`echo "$f" | cut -c3-`

        echo ""
        echo "Found a conflicting file: $f"

        # Grab the directory name
        d=`dirname "$f"`
echo "dirname is: $d" # DEV
        # Create the directory if it doesn't exist
        if [[ ! -d "$BACKUPDIR/$d" ]]; then
            echo "Creating new directory: $BACKUPDIR/$d"
            mkdir -p "$BACKUPDIR/$d" || error_exit "Failed to create backup subdirectory."
        fi

        # Grab the original file name
        oldname=`echo "$f" | sed "s/\(.*\)$CONFLICTSTR\(.*\)/\1\2/"` || error_exit "Failed to figure out the original file name."
echo "oldname is: $oldname" # DEV
        # Backup the (probably corrupt) file with the original name, removing from existing directory
        echo "Moving original to $BACKUPDIR/$oldname"
        mv "$oldname" "$BACKUPDIR/$d/" || error_exit "Failed to move original file to BACKUPDIR."
        
        # Rename the good file back to its original name
        echo "Renaming conflict file"
        mv "$f" "$oldname" || error_exit "Failed to rename conflict file."

        echo "Done. Moving on..."
    fi
done < <(find . -type f -print0)

echo ""
echo "Finished processing files. Have a great day, and don't forget to tip your barista."
echo ""