#!/bin/bash

# Function that builds a message generation:
# Note that we need to clean before in order to remove renamed messages.
build_generation()
{
    # This hack is needed because `catkin_make_isolated` does NOT provide any option to clean the package;
    # either way, even with `catkin_make clean`, it does NOT remove the package directory if .pyc files are inside it:
    for dir in $(tr ':' '\n' <<< "$PYTHONPATH")
    do
        cd "$dir"
        rm -rf test_rosbag
        cd "$OLDPWD"
    done

    catkin_make_isolated -q --pkg test_rosbag --cmake-args -DMSG_DIRECTORY="msg_$1" >/dev/null
}

# Function that saves the full text definition of a message:
save_msg()
{
    msg_type=${1/msg_*\//}
    msg_type=test_rosbag/${msg_type/.msg}

    saved_msg=${1/.msg/.saved}

    if [ ! -f "$saved_msg" ]
    then
        rosrun rosbag savemsg.py "$msg_type" > "$saved_msg"

        if [ $? -eq 0 ]
        then
            echo "Saved message $msg_type: $saved_msg"
        else
            echo "Failed to save message $msg_type!"
        fi
    else
        echo "Message $msg_type already saved in $saved_msg"
    fi
}

# Function that saves a message generation full definition (needed to create migration rules):
save_generation()
{
    msgs=$(find "msg_$1" -name "*.msg")

    for msg in $msgs
    do
        save_msg "$msg"
    done
}

# Function that creates migration rules from a previous message generation to the current one:
make_rules()
{
    saved_msgs=$(find "msg_$1" -name "*.saved")

    for saved_msg in $saved_msgs
    do
        rules=$(find msg_* test -name "*.bmr" -print0 | xargs -0)
        rule_file=${saved_msg/.saved/.bmr}

        if [ ! -f "$rule_file" ]
        then
            # Note that we can't redirect the output to >/dev/null because for renamed/moved messages we need to
            # provide the new message name.
            rosrun rosbag makerule.py "$saved_msg" "$rule_file" $rules

            if [ -f "$rule_file" ]
            then
                echo "Created rule for $saved_msg: $rule_file"
                echo "Set valid = True, the order and implement the update method, or remove it if you don't want it."
                echo "Then press ENTER."
                read
            else
                echo "No rule needed for $saved_msg!"
            fi
        else
            echo "Rule for $saved_msg already exists: $rule_file"
        fi
    done
}

# Take positional arguments that specifies the source and target message generations to create migration rules for:
if [ $# -eq 2 ]
then
    GENERATION_SOURCE=$1
    GENERATION_TARGET=$2
else
    echo "Usage  : $0 <source generation> <target generation>"
    echo "Example: $0 gen4 current"
    exit 1
fi

# Find the bag_migration_tests folder inside the test_rosbag package, since the .msg files are in the sub-folders
# there:
DESTINATION=$(rospack find test_rosbag)/bag_migration_tests

# Build messages for the source generation:
echo "Building generation: ${GENERATION_SOURCE}"
build_generation "${GENERATION_SOURCE}"

if [ $? -ne 0 ]
then
    >&2 echo "Failed to build messages for the source generation ${GENERATION_SOURCE}!"
    exit 1
fi

echo

# Save generation messages full text (needed to create migration rules):
echo "Saving messages full text for generation: ${GENERATION_SOURCE}"
cd "$DESTINATION"
save_generation "${GENERATION_SOURCE}"
cd "$OLDPWD"

if [ $? -ne 0 ]
then
    >&2 echo "Failed to save messages full text for the source generation ${GENERATION_SOURCE}!"
    exit 1
fi

echo

# Build messages for the target generation:
echo "Building generation: ${GENERATION_TARGET}"
build_generation "${GENERATION_TARGET}"

if [ $? -ne 0 ]
then
    >&2 echo "Failed to build messages for the target generation ${GENERATION_TARGET}!"
    exit 1
fi

echo

# Generate rules wrt to the source generation:
echo "Making rules from source generation '${GENERATION_SOURCE}' to target generation '${GENERATION_TARGET}'"
cd "$DESTINATION"
make_rules "${GENERATION_SOURCE}"
cd "$OLDPWD"

if [ $? -ne 0 ]
then
    >&2 echo "Failed to generate rules!"
    exit 1
fi

echo "* Remember that migration rules for renamed messages needs to be created manually!"
echo "* Also remember that the migration rules in the files generated by this script might belong to other messages,"
echo "  other than the one on the file name, so you should organize them properly!"

# We don't really need to change the directory back to the old one, it's done automatically on exit:
# cd $OLDPWD
