#!/usr/bin/env bash

# imports
source "${KOGITO_HOME}"/launch/logging.sh
source "${KOGITO_HOME}"/launch/kogito-persistence.sh

S2I_DESTINATION_DIR="${S2I_DESTINATION_DIR:-/tmp}"
S2I_ARTIFACTS_DIR="${S2I_DESTINATION_DIR}/artifacts"
S2I_SOURCE_DIR="${S2I_DESTINATION_DIR}/src"
PROJECT_GROUP_ID="${PROJECT_GROUP_ID:-com.company}"
PROJECT_ARTIFACT_ID="${PROJECT_ARTIFACT_ID:-project}"
PROJECT_VERSION="${PROJECT_VERSION:-1.0-SNAPSHOT}"
artifactDir="target"
readonly QUARKUS_RUNTIME_TYPE="quarkus"
readonly SPRINGBOOT_RUNTIME_TYPE="springboot"

if [ ! -z "${ARTIFACT_DIR}" ]; then
    artifactDir="${ARTIFACT_DIR}"
fi

# setup file permissions for injected content
if [ -d "${S2I_ARTIFACTS_DIR}" ]; then
    chmod -R ug+rwX "${S2I_ARTIFACTS_DIR}"
fi


function manage_incremental_build() {
    if [ -d /tmp/artifacts ]; then
        log_info "Expanding artifacts from incremental build..."
        ( cd /tmp/artifacts && tar cf - . ) | ( cd ${HOME} && tar xvf - )
        rm -rf /tmp/artifacts
    fi
}


function assemble_runtime() {
    # handle persistence files
    move_persistence_files
}


# copy already built artifacts to the runtime image.
function runtime_assemble() {
    log_info "-----> [s2i-core] Running runtime assemble script"
    cd ${S2I_DESTINATION_DIR}/src
    if [ "${BINARY_BUILD^^}" == "TRUE" ] || ls | grep -E '*.jar|classes|maven*|*-runner|target|quarkus-app' 1> /dev/null 2>&1; then
        log_info "-----> Binary build enabled, artifacts were uploaded directly to the image build"
        if ls target 1> /dev/null 2>&1; then
            log_info "-----> Entire target dir uploaded."
            cd "target"    
        fi

        local result=$(file -b --mime-type *-runner | grep x-executable)
        if [ "$result" == "application/x-executable" ]; then
            log_info "-----> Found binary file, native build."
            NATIVE="TRUE"

        else
            if ls | grep -E '*-runner.jar' 1> /dev/null 2>&1;then
                log_info "-----> Found Quarkus runner.jar file, not native build."
                NATIVE="FALSE"

            elif ls | grep -E 'quarkus-app/*-run.jar' 1> /dev/null 2>&1;then
                log_info "-----> Found Quarkus app.jar file, not native build."
                NATIVE="FALSE"
            fi
        fi

        log_info "-----> Cleaning up unneeded jar files"
        rm -rfv *-tests.jar
        rm -rfv *-sources.jar

        log_info "-----> Copying uploaded files to "${KOGITO_HOME}""
        artifactDir="."
        ARTIFACT_DIR=$artifactDir
        copy_kogito_app
        copy_persistence_files
    else
        cp -Rv --parents ./* "${KOGITO_HOME}"/
    fi
    assemble_runtime
    log_info "-----> Cleaning up s2i directory"
    rm -rfv ${S2I_DESTINATION_DIR}/src/*
}

function build_kogito_app() {
    local RUNTIME_TYPE="${1:-$QUARKUS_RUNTIME_TYPE}"
    cd "${S2I_SOURCE_DIR}"

    nativeBuild=""
    if [ "${NATIVE^^}" == "TRUE" ]; then
        nativeBuild="-Pnative"
    fi

    if [ "${SCRIPT_DEBUG}" != "true" ]; then
        export MAVEN_ARGS_APPEND="${MAVEN_ARGS_APPEND} --batch-mode"
    fi

    if [ -f "pom.xml" ]; then
        log_info "---> Building application from source..."
        $MAVEN_HOME/bin/mvn clean package ${MAVEN_ARGS_APPEND} ${KOGITO_OPTS} ${nativeBuild} -s "${KOGITO_HOME}"/.m2/settings.xml \
	    -DskipTests -Dmaven.test.skip -Dmaven.javadoc.skip=true -Dmaven.site.skip=true -Dmaven.source.skip=true \
	    -Djacoco.skip=true -Dcheckstyle.skip=true -Dfindbugs.skip=true -Dpmd.skip=true -Dfabric8.skip=true

    else
        log_info "---> Generating $RUNTIME_TYPE project structure for $PROJECT_ARTIFACT_ID..."
        local quarkus_version
        if [ "${RUNTIME_TYPE}" == "${QUARKUS_RUNTIME_TYPE}" ]; then

            local quarkus_plugin="${QUARKUS_PLUGIN:-io.quarkus:quarkus-maven-plugin}"
            if [[ "${JBOSS_IMAGE_NAME}" =~ "rhpam-7" ]]; then
                quarkus_plugin="${QUARKUS_PLUGIN:-com.redhat.quarkus.platform:quarkus-maven-plugin}"
            fi

            IFS=':' read -ra GAV <<< "${quarkus_plugin}"
            for i in "${GAV[@]}"; do
                if [[ "$i" =~ ^[0-9]{0,2}\.[0-9]{0,3} ]]; then
                    log_info "version [${i}] provided through QUARKUS_PLUGIN env."
                    quarkus_version=${i}
                else
                    quarkus_version=$(get_quarkus_version) || exit 1
                fi
            done

            log_info "----> Using Quarkus version ${quarkus_version} to bootstrap the application."

            $MAVEN_HOME/bin/mvn -U -B ${MAVEN_ARGS_APPEND} -s "${KOGITO_HOME}"/.m2/settings.xml $(get_quarkus_platform_properties) \
                "${quarkus_plugin}":"${quarkus_version}":create  \
                    -DprojectGroupId=$PROJECT_GROUP_ID \
                    -DprojectArtifactId=$PROJECT_ARTIFACT_ID \
                    -DprojectVersion=$PROJECT_VERSION \
                    -Dextensions="kogito,quarkus-smallrye-health,quarkus-smallrye-openapi"

        elif [ "${RUNTIME_TYPE}" == "${SPRINGBOOT_RUNTIME_TYPE}" ]; then
            log_info "----> Using Spring Boot to bootstrap the application."
            $MAVEN_HOME/bin/mvn archetype:generate -U -B -DinteractiveMode=false -DarchetypeGroupId=org.kie.kogito \
                -DarchetypeArtifactId=kogito-spring-boot-archetype -DarchetypeVersion=$KOGITO_VERSION \
                -DgroupId=$PROJECT_GROUP_ID -DartifactId=$PROJECT_ARTIFACT_ID -Dversion=$PROJECT_VERSION \
                ${MAVEN_ARGS_APPEND} -s "${KOGITO_HOME}"/.m2/settings.xml
        else
            log_error "---> Invalid RUNTIME_TYPE(${RUNTIME_TYPE}) provided, failing build..."
            exit 1
        fi

        # remove resources generated by the archetype
        log_info "--> Remove archetype generated resources"
        rm -rfv $PROJECT_ARTIFACT_ID/src/main/resources/*.{bpm,bpmn2,dmn,drl}

        local require_sw
        # copy resources into the generated project
        for item in *
        do
            if [ -d "${item}" ] && [ "${item}" == "$PROJECT_ARTIFACT_ID" ]; then
                log_info "--> Skipping generated project ..."
            else
                log_info "--> Copying resource ${item}"
                cp -Rv "${item}" $PROJECT_ARTIFACT_ID/src/main/resources

                if [[ ${item} =~ .*\.sw\.(yaml|yml|json) ]]; then
                    if [[ "${RUNTIME_TYPE}" == "${QUARKUS_RUNTIME_TYPE}" ]]; then
                        log_info "--> Found Serverless Workflow file. Will add Kogito Quarkus Workflows extension to the project."
                        require_sw="true"
                    else
                        log_warning "--> Builds from Serverless Workflow files are not supported for SpringBoot. Please build your project locally or use Quarkus."
                        break
                    fi
                fi
            fi
        done

        # move all project content into the current directory
        mv -v $PROJECT_ARTIFACT_ID/* .

        # add extension if needed
        if [ "${require_sw}" == "true" ]; then
            log_info "--> Adding Kogito Quarkus Workflows extension to the generated project."

            # we must set the evaluate version since forceStdout is not available in previous versions
            local quarkus_version
            quarkus_version=$(get_quarkus_version) || exit 1
            log_info "--> Quarkus version is '$quarkus_version'"

            $MAVEN_HOME/bin/mvn ${MAVEN_ARGS_APPEND} -s "${KOGITO_HOME}"/.m2/settings.xml $(get_quarkus_platform_properties) \
                "${quarkus_plugin}":"${quarkus_version}":add-extension \
                -Dextensions="org.kie.kogito:kogito-quarkus-serverless-workflow"
        fi

        $MAVEN_HOME/bin/mvn clean package ${MAVEN_ARGS_APPEND} ${KOGITO_OPTS} ${nativeBuild} -s "${KOGITO_HOME}"/.m2/settings.xml \
            -DskipTests -Dmaven.test.skip -Dmaven.javadoc.skip=true -Dmaven.site.skip=true -Dmaven.source.skip=true \
            -Djacoco.skip=true -Dcheckstyle.skip=true -Dfindbugs.skip=true -Dpmd.skip=true -Dfabric8.skip=true
    fi

    log_info "---> Build finished, installing application from path $(pwd)"
}

function copy_kogito_app() {

    if [ "${NATIVE^^}" == "TRUE" ]; then
        if ls $artifactDir/*-runner 1> /dev/null 2>&1; then
            # quarkus native build binary
            log_info "---> Installing native application binaries"
            cp -v $artifactDir/*-runner "${KOGITO_HOME}"/bin/
            chmod +x "${KOGITO_HOME}"/bin/*-runner
        fi

    elif ls $artifactDir/*-runner.jar 1> /dev/null 2>&1; then
        # handle quarkus build files
        log_info "---> Installing runner jar file"
        cp -v $artifactDir/*-runner.jar "${KOGITO_HOME}"/bin
        if [ -d "${artifactDir}/lib" ]; then
            log_info "---> Copying application libraries"
            cp -r $artifactDir/lib/ "${KOGITO_HOME}"/bin
        fi

    elif ls $artifactDir/quarkus-app/*-run.jar 1> /dev/null 2>&1; then
        # handle quarkus 1.12+ build files
        log_info "---> Installing Quarkus 1.12+ Application files"
        # copy everything that resides on quarkus-app directory
        cp -rv $artifactDir/quarkus-app/* "${KOGITO_HOME}"/bin

    else
        # handle normal java builds
        log_info "---> Installing common application binaries"
        cp -v $artifactDir/*.jar "${KOGITO_HOME}"/bin
    fi
}

function get_runtime_type() {
    allowed_runtime_values=("$QUARKUS_RUNTIME_TYPE" "$SPRINGBOOT_RUNTIME_TYPE")
    local runtime_type="${RUNTIME_TYPE:-$QUARKUS_RUNTIME_TYPE}"

    if [[ ! "${allowed_runtime_values[*]}" =~ ${RUNTIME_TYPE} ]]; then
        log_warning "RUNTIME_TYPE ${RUNTIME_TYPE} is not allowed, the allowed types are [${allowed_runtime_values[*]}]. Application might fail"
    fi

    log_info "---> Setting RUNTIME_TYPE to ${runtime_type}"
    echo "${runtime_type}"
}

function get_quarkus_platform_properties() {
    local quarkus_platform_group_id="${QUARKUS_PLATFORM_GROUP_ID:-io.quarkus.platform}"
    local quarkus_platform_artifact_id="${QUARKUS_PLATFORM_ARTIFACT_ID:-quarkus-bom}"
    if [[ "${JBOSS_IMAGE_NAME}" =~ "rhpam-7" ]]; then
        quarkus_platform_group_id="${QUARKUS_PLATFORM_GROUP_ID:-com.redhat.quarkus.platform}"
        quarkus_platform_artifact_id="${QUARKUS_PLATFORM_ARTIFACT_ID:-quarkus-bom}"
    fi

    echo " -DplatformGroupId=${quarkus_platform_group_id} -DplatformArtifactId=${quarkus_platform_artifact_id} -DplatformVersion=$(get_quarkus_version)"
}

function get_quarkus_version() {
    local quarkus_version="${QUARKUS_VERSION}"
    if [ "${QUARKUS_VERSION}x" = "x" ]; then
        log_info "----> Trying to retrieve Quarkus version from org.kie.kogito:kogito-build-parent:${KOGITO_VERSION}"
        ver=$($MAVEN_HOME/bin/mvn ${MAVEN_ARGS_APPEND} -s "${KOGITO_HOME}"/.m2/settings.xml help:evaluate -q \
            -Dartifact=org.kie.kogito:kogito-build-parent:"${KOGITO_VERSION}" \
            -Dexpression=version.io.quarkus \
            -DforceStdout)

        if [[ ! "$ver" =~ [0-9]{0,2}\.[0-9]{0,3} ]]; then
            log_error "----> Impossible to get Quarkus version from the generated Maven project (output: '$ver'), failing build"
            exit 1
        fi
	    quarkus_version=$ver
    fi
    echo $quarkus_version
}
