#!/bin/bash
#-------------------------------------------------------------------------------
# Copyright 2023 Norconex Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#-------------------------------------------------------------------------------

# Store the Maven module artifact names as well as their relative folder names
# for modified modules and their dependents within this project.
#
# Relies on  ./github/outputs/all_changed_files.txt to be present, 
# generated by 'tj-actions/changed-files' action.
#
# The following will be writen under ./github/outputs/
#
#   changed-module-artifacts.txt      -> changed artifact ids
#   changed-module-dirs.txt           -> changed directories
#   changed-module-artifacts-deps.txt -> changed artifact ids incl. dependents
#   changed-module-dirs-deps.txt      -> changed directories incl. dependents
#   all-module-artifacts.txt          -> all artifacts, regardless of changes
#   all-module-dirs.txt               -> all directories, regardless of changes
#   any-module-changed.txt            -> true|false if at least one module 
#                                        changed, including parent
#     
# The files will be empty if the parent module was modified, which
# equates to all modules being modified.

OUTPUTS_DIR=.github/outputs
CHANGED_DIRS_FILE="${OUTPUTS_DIR}/all_changed_files.txt"

MODULE_ARTIFACTS_FILE="${OUTPUTS_DIR}/changed-module-artifacts.txt"
MODULE_DIRS_FILE="${OUTPUTS_DIR}/changed-module-dirs.txt"
MODULE_ARTIFACTS_DEPS_FILE="${OUTPUTS_DIR}/changed-module-artifacts-deps.txt"
MODULE_DIRS_DEPS_FILE="${OUTPUTS_DIR}/changed-module-dirs-deps.txt"
MODULE_ARTIFACTS_ALL_FILE="${OUTPUTS_DIR}/all-module-artifacts.txt"
MODULE_DIRS_ALL_FILE="${OUTPUTS_DIR}/all-module-dirs.txt"
MODULE_ANY_CHANGED="${OUTPUTS_DIR}/any-module-changed.txt"

# Make sure the files exist and empty by default
touch $MODULE_ARTIFACTS_FILE
touch $MODULE_DIRS_FILE
touch $MODULE_ARTIFACTS_DEPS_FILE
touch $MODULE_DIRS_DEPS_FILE
touch $MODULE_ARTIFACTS_ALL_FILE
touch $MODULE_DIRS_ALL_FILE
touch $MODULE_DIRS_ALL_FILE
echo "true" > $MODULE_ANY_CHANGED

# if no changes at all, abort now
if [ ! -s $CHANGED_DIRS_FILE ]; then
    echo "No changes detected.";
    exit;
fi

# Get changed directory names and artifact ids
module_dirs="";
module_artifacts="";
for dir in $(cat $CHANGED_DIRS_FILE); do
    # if the parent module was modified, abort now.
    if [ $dir == "." ]; then
        echo "Change detected in parent module.";
        exit;
    fi
    # if not the parent, keep it
    if [ -f "${dir}/pom.xml" ]; then
        module_dirs="${module_dirs} ${dir}";
        # grab first artifactId that does not contain "parent"
        artifactId=$(
            grep -m2 "<artifactId>" "${dir}/pom.xml" \
            | grep -v parent \
            | sed 's/.*>\(.*\)<.*/\1/' \
            | xargs
        );
        module_artifacts="${module_artifacts} :${artifactId}";
    fi
done

if [ -z "$module_artifacts" ]; then
    echo "Aborting: none of the modules include any of the latest changes.";
    echo "false" > $MODULE_ANY_CHANGED
    exit;
fi

echo "Changed artifacts:                 $module_artifacts";
echo "Changed directories:               $module_dirs";
echo "$module_artifacts" | xargs > $MODULE_ARTIFACTS_FILE;
echo "$module_dirs" | xargs > $MODULE_DIRS_FILE;

# Get w/ dependent artifacts
include_ids=$(echo "$module_artifacts" | xargs | tr ' ' ',');
module_artifacts_deps="$(mvn dependency:tree \
    -Dincludes=${include_ids} \
    -Dtokens=whitespace \
    | grep -A1 maven-dependency-plugin \
    | grep -v "\-\-" \
    | sed 's/\[INFO\] //' \
    | sort \
    | uniq \
    | sed 's/^[^:]*\(:[^:]*\):.*/\1/' \
    | tr '\n' ' ' \
    | xargs)";

echo "Changed artifacts and dependents:   $module_artifacts_deps";
echo "$module_artifacts_deps" > $MODULE_ARTIFACTS_DEPS_FILE;

# Get w/ dependent directories
module_dirs_deps=""
all_module_dirs=""
all_module_artifacts=""
for pom in $(find . -name "pom.xml"); do

    dir=$(echo $pom | sed -n 's|^\./\(.*\)/pom.xml$|\1|gp');
    all_module_dirs="${all_module_dirs} ${dir}";

    # grab first artifactId after parent.
    artifactId=":$(
        grep -m2 "<artifactId>" "${pom}" \
        | grep -v parent \
        | sed 's/.*>\(.*\)<.*/\1/' \
        | xargs)";
    all_module_artifacts="${all_module_artifacts} ${artifactId}"

    found=$(echo $module_artifacts_deps \
        | grep -E "(^|\s)${artifactId}(\s|$)" \
        | wc -l );
    if [ $found -gt 0 ]; then
        module_dirs_deps="${module_dirs_deps} ${dir}";
    fi

done

echo "Changed directories and dependents:${module_dirs_deps}";
echo "$module_dirs_deps" | xargs > $MODULE_DIRS_DEPS_FILE;

echo "$all_module_artifacts" | xargs > $MODULE_ARTIFACTS_ALL_FILE;
echo "$all_module_dirs" | xargs > $MODULE_DIRS_ALL_FILE;
