#!/usr/bin/env bash

# Copyright (C) 2020 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -eo pipefail

API_BENCH_EXECUTABLE=$(basename "$0")

pushd "$(dirname "$0")" &> /dev/null
API_BENCH_DIR=$PWD
popd &> /dev/null

CURRENT_BENCHMARK_ID=0
BENCHMARKS=()
BUILD_DIRECTORIES=()
REFERENCES=("X")
CURRENT_API=()
UPCOMING_API=()
ARCHS=${ARCHS:-$(uname -m)}
CONFIGURATION=${CONFIGURATION:-Release}

shouldBuild=true
runReferences=true
verbose=false
iterations=5

log() {
    if [ "$verbose" == true ]; then
        echo "$*"
    fi
}

printUsage() {
    cat <<EOF
usage: $API_BENCH_EXECUTABLE [-h|--help] [--no-build] [--no-reference(s)] [-v|--verbose] [--iterations <n=$iterations>] <build_directory1> [<build_directory2> ...]
EOF
    exit 0
}

collectFlags() {
    while [ $# -gt 0 ]; do
        case "$1" in
            -h|--help)
                printUsage
                ;;
            --no-build)
                shouldBuild=false
                ;;
            --no-reference|--no-references)
                runReferences=false
                ;;
            -v|--verbose)
                verbose=true
                ;;
            --iterations)
                shift
                iterations=$1
                ;;
            *)
                BUILD_DIRECTORIES=("$@")
                break 2
                ;;
        esac
        shift
  done

  if [ ${#BUILD_DIRECTORIES[@]} -lt 1 ]; then
      printUsage
      exit 1
  fi

  for i in "${!BUILD_DIRECTORIES[@]}"; do
      local buildDirectory
      buildDirectory=${BUILD_DIRECTORIES[$i]}

      if ! [ -d "$buildDirectory" ]; then
          echo "No such file or directory: $buildDirectory"
          exit 1
      fi

      pushd "$buildDirectory" &> /dev/null
      BUILD_DIRECTORIES[$i]=$PWD
      popd &> /dev/null
  done
}

collectBenchmarkDir() {
    local benchmarkVar=$1
    local benchmarkDir=$2
    benchmarks=("$API_BENCH_DIR"/"$benchmarkDir"/*)
    for benchmark in "${benchmarks[@]}"; do
        local benchmarkID=$CURRENT_BENCHMARK_ID
        CURRENT_BENCHMARK_ID=$((CURRENT_BENCHMARK_ID+1))
        pushd "$benchmark" &> /dev/null
        BENCHMARKS[$benchmarkID]=$PWD
        eval "${benchmarkVar}[\$benchmarkID]=$benchmarkID"
        popd &> /dev/null
    done
}

collectBenchmarks() {
    if [ "$runReferences" == true ]; then
        collectBenchmarkDir "REFERENCES" References
    fi
    collectBenchmarkDir "CURRENT_API" CurrentAPI
    collectBenchmarkDir "UPCOMING_API" UpcomingAPI
}

forEachBenchmark() {
    local functor
    functor="$1"
    declare "$functor"
    for benchmarkID in "${!BENCHMARKS[@]}"; do
        local benchmark
        benchmark=${BENCHMARKS[$benchmarkID]}
        pushd "$benchmark" &> /dev/null
        BENCHMARK_ID=$benchmarkID
        BENCHMARK_NAME=$(basename "$benchmark")
        "$functor"
        popd &> /dev/null
    done
}

buildBenchmark() {
    project=$BENCHMARK_NAME.xcodeproj

    if ! [ -e "$project" ]; then
        return
    fi

    log "Building $BENCHMARK_NAME... (FRAMEWORK_SEARCH_PATHS='$BUILD_DIRECTORY')"
    xcodebuild -project "$project" -target "$BENCHMARK_NAME" -configuration "$CONFIGURATION" build "FRAMEWORK_SEARCH_PATHS='$BUILD_DIRECTORY'" "ARCHS='$ARCHS'"
}

build() {
    BUILD_DIRECTORY=$1
    forEachBenchmark "buildBenchmark"
}

runJSBenchmark() {
    "$DYLD_FRAMEWORK_PATH/jsc" "$BENCHMARK_NAME.js"
}

runNativeBenchmark() {
    pushd "build/$CONFIGURATION" &> /dev/null
    "./$BENCHMARK_NAME"
    local exitCode=$?
    if [ $exitCode -ne 0 ]; then
        echo "Benchmark exited with an error: $PWD/$BENCHMARK_NAME exited with $exitCode" 1>&2
    fi
    popd &> /dev/null
    return $exitCode
}

runBenchmarkIteration() {
    if [ -e "build" ]; then
        runNativeBenchmark
    else
        runJSBenchmark
    fi
}

runBenchmark() {
    log "Running $BENCHMARK_NAME..."

    local result
    result=$(runBenchmarkIteration)
    if [ $? -ne 0 ]; then
        exit 1
    fi
    RESULTS[$((BENCHMARK_ID * iterations + ITERATION))]=$result
    log "Finished in ${result}ms"
}

computeAverage() {
    local benchmarkID benchmark sum avg
    benchmarkID=$1
    benchmark=${BENCHMARKS[$benchmarkID]}
    sum=0
    for iteration in $(seq 0 1 $((iterations - 1))); do
        local result
        result=${RESULTS[$((benchmarkID * iterations + iteration))]}
        sum=$((sum + result))
    done
    bc <<< "$sum.0 / $iterations.0"
}

printAverage() {
    local benchmarkID benchmark name avg
    benchmarkID=$1
    avg=$2
    benchmark=${BENCHMARKS[$benchmarkID]}
    name=$(basename "$benchmark")
    echo "$name: ${avg}ms"
}

printBenchmark() {
    printAverage "$@" "$(computeAverage "$@")"
}

printResults() {
    local buildDirectory=$1

    echo "Results for $buildDirectory ($iterations iterations)"
    echo "================================================================================"

    if [ "$runReferences" == true ]; then
        echo ""
        echo "References:"
        echo "----------------------------------------"
        for benchmarkID in "${REFERENCES[@]}"; do
            printBenchmark "$benchmarkID"
        done
    fi

    local score count
    score=0
    count=0
    
    printCategory() {
        local category=$1

        echo ""
        echo "$category:"
        echo "----------------------------------------"

        for benchmarkID in $(eval 'echo ${'"$category"'[@]}'); do
            avg=$(computeAverage "$benchmarkID")
            printAverage "$benchmarkID" "$avg"
            count=$((count + 1))
            score=$(echo "$score" "$avg" | awk '{print ($1 + log($2)) }')
        done
    }
    printCategory "CURRENT_API"
    printCategory "UPCOMING_API"
    score=$(echo "$score" "$count" | awk '{ print(5000.0 / exp($1 / $2)) }')

    echo ""
    echo "Score: $score"
}

run() {
    local buildDirectory
    buildDirectory=$1

    export DYLD_FRAMEWORK_PATH=$buildDirectory
    for iteration in $(seq 0 1 $((iterations-1))); do
        ITERATION=$iteration
        forEachBenchmark "runBenchmark"
    done

    printResults "$buildDirectory"
}


main() {
    collectFlags "$@"
    collectBenchmarks
    for buildDirectory in "${BUILD_DIRECTORIES[@]}"; do
        if [ "$shouldBuild" == true ]; then
            build "$buildDirectory"
        fi

        run "$buildDirectory"
    done
}

main "$@"
