#!/usr/bin/env bash
# Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
#
# 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
#
#   https://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.

# A shell script to run Pkl and capture its outputs.
# This script is executed as a part of the `pkl_eval` and `pkl_test` Bazel rules.
#
# The script has the following structure:
# 1. Create symlinks to the working directory, for all files needed when running Pkl.
# 2. Formulate the output arguments provided to Pkl, in order for Pkl to render files in an expected place.
# 3. Formulate the `--cache-dir` argument with path to the cache directory (if provided).
# 4. Execute the Pkl command provided. (Either `eval` or `test`).
# 5. Capture the output(s) of Pkl.
# 6. Move files generated by Pkl to the location Bazel expects output files to be (if running the `eval` command).

expected_output=$1
command=$2
executable=$3
symlinks_json_file_path=$4
symlinks_executable=$5
format_args=$6
entrypoints=$7
multiple_outputs=$8
working_dir=$9
cache_dir=${10}
suite_name=${11}
shift 11

properties_and_expressions=("$@")

"$symlinks_executable" "$symlinks_json_file_path"

ret=$?
if [[ $ret != 0 ]]; then
    echo "Failed creating dependency symlinks in Pkl rule setup." >&2
    exit 1
fi

if [ "$command" == "eval" ]; then
  if [ "$multiple_outputs" == "true" ]; then
    mkdir _generated_files
    output_args=( "--multiple-file-output-path" "_generated_files")
  else
    output_args=("--output-path" "$expected_output")
  fi
  test_args=()
elif [[ "$command" == "test" ]]; then
  output_args=()
  if [[ -n "${XML_OUTPUT_FILE}" ]]; then
    test_args=("--junit-reports" "${working_dir}" "--junit-aggregate-reports" "--junit-aggregate-suite-name" "${suite_name}")
  else
    test_args=()
  fi
else
  echo "invalid command: $command" >&2
  exit 1
fi

cache_args=()
if [[ -n "$cache_dir" ]]; then
  mv "$cache_dir" "$working_dir"/../cache
  cache_args=("--cache-dir" "../cache")
fi

output=$($executable "$command" $format_args "${properties_and_expressions[@]}" $expression_args --working-dir "${working_dir}" "${cache_args[@]}" "${test_args[@]}" "${output_args[@]}" $entrypoints)

ret=$?

if [[ "$command" == "test" ]]; then
  if [ -f "${working_dir}/${suite_name}.xml" ]; then
    mv "${working_dir}/${suite_name}.xml" "${XML_OUTPUT_FILE}"
  fi
fi

if [[ $ret != 0 ]]; then
  if [ "$command" == eval ]; then
    echo "Failed processing PKL configuration with entrypoint(s) '$entrypoints' (PWD: $(pwd)):" >&2
    echo "${output}"
  else
    echo "Test failed."
    echo "${output}"
  fi
  exit 1
fi


if [[ "$command" == eval ]]; then
  if [ "$multiple_outputs" == true ]; then
    if [ -d "${working_dir}/_generated_files" ]; then
      mv "${working_dir}/_generated_files"/* "$expected_output"
    fi
  else
    mv "${working_dir}/${expected_output}" "$expected_output"
  fi
fi
