#!/bin/bash -e

# Copyright (c) 2023 Project CHIP Authors
#
# 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.

# Usage: configure [OPTIONS] [--project=... [PROJECT OPTIONS]]
#
# Configures a stand-alone build for a CHIP application in the current
# directory and creates a `ninja-build` wrapper script to build it. Should
# generally be run from an empty build directory (i.e. out-of-tree).
#
# This is intended to be used in the context of an external build system and
# represents a light-weight alternative to bootstrapping the full Pigweed build
# environment (via scripts/activate.sh). The pigweed git sub-module must still
# be present though.
#
# External tool dependencies: bash, python3, gn, ninja
#
# The zap-cli code generator and a small number of Python modules are
# downloaded if necessary (see scripts/setup/requirements.build.txt) and
# installed in a build environment directory. By default this is local to
# the build directory, but an external directory can be specified using the
# --build-env-dir option. The build environment directory can be shared by any
# number of build directories, independently of target / tool chain.

set -o pipefail
shopt -s extglob

function usage() { # status
    info "Usage: $0 [OPTIONS] [--project=... [PROJECT OPTIONS]]"
    info "Options:"
    info "  --build-env-dir=DIR   Directory to create (host) build environment in"
    info "  --project=DIR         Sub-directory to build, eg examples/lighting-app/linux"
    info ""
    info "Project options (mapped to GN build args):"
    info "  --enable-<ARG>[=no]   Enables (or disables with '=no') a bool build arg"
    info "  --<ARG>=<VALUE>       Sets a (non-bool) build arg to the given value"
    info "  GN argument names can be specified with '-' instead of '_' and prefixes"
    info "  like 'chip_' can be ommitted from names. For the full list of available"
    info "  build arguments, see the generated args.configured file."
    info ""
    info "  By default, the toolchain for the GN build will be configured from the usual"
    info "  environment variables (CC, CXX, AR, CFLAGS, CXXFLAGS, ...), falling back to"
    info "  default tool names (CC=cc, ...). When using this script within an external"
    info "  build system, toolchain environment variables should be populated."
    exit "$1"
}

function main() { # ...
    CHIP_ROOT=$(cd "$(dirname "$0")/.." && pwd)
    BUILD_ENV_DEPS=(
        "${CHIP_ROOT}/scripts/setup/requirements.build.txt"
        "${CHIP_ROOT}/scripts/setup/constraints.txt"
        "${CHIP_ROOT}/scripts/setup/zap.version"
    )

    # Parse global options, process VAR=VALUE style arguments, and collect project options
    BUILD_ENV_DIR=
    PROJECT=
    PROJECT_ARGS=()
    while [[ $# -gt 0 ]]; do
        case "$1" in
        --help) usage 0 ;;
        --build-env-dir=*) BUILD_ENV_DIR="${1#*=}" ;;
        --project=*) PROJECT="${1#*=}" ;;
        +([A-Z_])=*) export "$1" ;;
        *)
            [[ -n "$PROJECT" ]] || fail "Invalid argument: '$1'"
            PROJECT_ARGS+=("$1")
            ;;
        esac
        shift
    done

    # Ensure we have something to do
    [[ -n "$PROJECT" || -n "$BUILD_ENV_DIR" ]] || usage 1

    if [[ -n "$PROJECT" ]]; then
        local subdir="$(cd "${CHIP_ROOT}/${PROJECT}" 2>/dev/null && pwd)"
        [[ -n "$subdir" && -r "${subdir}/.gn" ]] || fail "Invalid project '${PROJECT}'"
        PROJECT="${subdir#${CHIP_ROOT}/}"
        [[ "$subdir" == "${CHIP_ROOT}/${PROJECT}" ]] || fail "Unable to determine project path"
    fi

    check_binary gn GN
    check_binary ninja NINJA

    # Work out build and environment directories
    if [[ "$PWD" == "$CHIP_ROOT" ]]; then
        BUILD_DIR="out/configured"
        NINJA_HINT="ninja -C ${BUILD_DIR}"
    else
        BUILD_DIR="."
        NINJA_HINT="ninja"
    fi

    if [[ -n "$BUILD_ENV_DIR" ]]; then
        mkdir -p "$BUILD_ENV_DIR"
        BUILD_ENV_PATH="$(cd "$BUILD_ENV_DIR" && pwd)"
        [[ -n "$BUILD_ENV_PATH" ]] || fail "Invalid build-env-dir '${BUILD_ENV_DIR}'"
        BUILD_ENV_DIR="$BUILD_ENV_PATH" # absolute
    else
        BUILD_ENV_DIR="build-env" # relative to BUILD_DIR
        BUILD_ENV_PATH="${BUILD_DIR}/${BUILD_ENV_DIR}"
    fi

    # Create the build environment if necessary
    if ! check_build_env; then
        check_python
        configure_python_env
        if ! check_binary zap-cli; then
            download_zap
        fi
        finalize_build_env
    fi

    # Configure the project (if requested)
    if [[ -z "$PROJECT" ]]; then
        info "Build environment created. (Specify --project=DIR to configure a build.)"
        return
    fi

    [[ "$BUILD_DIR" != "." ]] && info "Configuring in-tree, will build in ${BUILD_DIR}"

    create_empty_pw_env
    guess_toolchain
    gn_generate "${PROJECT_ARGS[@]}"
    create_ninja_wrapper
    info "You can now run ./ninja-build (or $NINJA_HINT)"
}

function create_empty_pw_env() {
    # The Pigweed environment ("//build_overrides/pigweed_environment.gni") is
    # imported unconditionally in various build files, so ensure it exists.
    local gni="build_overrides/pigweed_environment.gni"
    if [[ -d "${CHIP_ROOT}/$(dirname "$gni")" ]]; then
        if safe_to_clobber "$gni"; then
            info "Creating empty $gni in source tree"
            echo "# ${CONFIGURE_MARKER}" >"${CHIP_ROOT}/${gni}"
        else
            info "Warning: Leaving existing $gni in place, this might affect the build configuration."
        fi
    fi
}

function guess_toolchain() {
    # There is no widely used standard command for the C++ compiler (analogous to
    # `cc` for the C compiler), so if neither CC nor CXX are defined try to guess.
    if [[ -z "$CC" && -z "$CXX" ]] && have_binary cc; then
        local probe="$(cc -E - <<<'gnu=__GNUC__ clang=__clang__' 2>/dev/null)"
        # Check for clang first because it also defines __GNUC__
        if [[ "$probe" =~ clang=[1-9] ]] && have_binary clang && have_binary clang++; then
            info "Guessing CC=clang CXX=clang++ because cc appears to be clang"
            export CC=clang CXX=clang++
        elif [[ "$probe" =~ gnu=[1-9] ]] && have_binary gcc && have_binary g++; then
            info "Guessing CC=gcc CXX=g++ because cc appears to be gcc"
            export CC=gcc CXX=g++
        else
            info "Unable to guess c++ compiler: $probe"
        fi
    fi
}

function gn_generate() { # [project options]
    mkdir -p "${BUILD_DIR}"
    ensure_no_clobber "${BUILD_DIR}/args.gn"

    # Pass --script-executable to all `gn` calls so scripts run in our venv
    local gn=(gn --script-executable="${BUILD_ENV_DIR}/bin/python" --root="${CHIP_ROOT}/${PROJECT}")

    # Run gn gen with an empty args.gn first so we can list all arguments
    info "Configuring gn build arguments (see $BUILD_DIR/args.configured for full list)"
    {
        echo "# ${CONFIGURE_MARKER}"
        echo "# project root: ${PROJECT}"
    } >"${BUILD_DIR}/args.gn"
    "${gn[@]}" -q gen "$BUILD_DIR"

    # Use the argument list to drive the mapping of our command line options to GN args
    call_impl process_project_args <("${gn[@]}" args "$BUILD_DIR" --list --json) "$@" >>"${BUILD_DIR}/args.gn"
    "${gn[@]}" args "$BUILD_DIR" --list >"${BUILD_DIR}/args.configured"

    # Now gn gen with the arguments we have configured.
    info "Running gn gen to generate ninja files"
    "${gn[@]}" -q gen "$BUILD_DIR"
}

function create_ninja_wrapper() {
    local wrapper="ninja-build"
    ensure_no_clobber "$wrapper"
    {
        echo "#!/bin/bash -e"
        echo "# ${CONFIGURE_MARKER}"
        if [[ "$BUILD_DIR" != "." ]]; then
            echo 'args=(-C "$(dirname "$0")/'"${BUILD_DIR}"'")'
        else
            echo 'args=() dir="$(dirname "$0")"'
            echo '[[ "$dir" != "." ]] && args=(-C "$dir")'
        fi
        echo 'exec ninja "${args[@]}" "$@"'
    } >"$wrapper"
    chmod a+x "$wrapper"
}

function check_build_env() {
    generate_build_env_cksum # re-used by finalize_build_env
    [[ -r "${BUILD_ENV_PATH}/.cksum" ]] || return 1
    read -r <"${BUILD_ENV_PATH}/.cksum" || true
    [[ "$REPLY" == "$CURRENT_ENV_CKSUM" ]] || return 1

    [[ -r "${BUILD_ENV_PATH}/bin/activate" ]] || return 1
    info "Using existing build environment: ${BUILD_ENV_PATH}"
    PYTHON="${BUILD_ENV_PATH}/bin/python"
}

function configure_python_env() {
    progress "Setting up Python venv"
    "$PYTHON" -m venv --clear "$BUILD_ENV_PATH"
    info "$BUILD_ENV_PATH"

    # Install our auto-loading venvactivate module so that running scripts via
    # the venv python has the side-effect of fully activating the environment.
    local sitepkgs=("${BUILD_ENV_PATH}/lib/python"*"/site-packages")
    [[ -d "$sitepkgs" ]] || fail "Failed to locate venv site-packages"
    cp "${CHIP_ROOT}/scripts/configure.venv/venvactivate".{pth,py} "${sitepkgs}/"

    progress "Installing Python build dependencies"
    "${BUILD_ENV_PATH}/bin/pip" install --require-virtualenv --quiet --upgrade pip wheel
    "${BUILD_ENV_PATH}/bin/pip" install --require-virtualenv --quiet \
        -r "${CHIP_ROOT}/scripts/setup/requirements.build.txt" \
        -c "${CHIP_ROOT}/scripts/setup/constraints.txt"
    info "ok"
}

function generate_build_env_cksum() {
    # Conservatively assume that any change to this script or BUILD_ENV_DEPS invalidates the environment
    CURRENT_ENV_CKSUM="$(cat "$0" "${BUILD_ENV_DEPS[@]}" | cksum)"
    [[ -n "$CURRENT_ENV_CKSUM" ]] || fail "Failed to generate build environment checksum"
}

function finalize_build_env() {
    echo "$CURRENT_ENV_CKSUM" >"${BUILD_ENV_PATH}/.cksum"
}

function download_zap() {
    local version platform arch
    read -r version <"${CHIP_ROOT}/scripts/setup/zap.version"
    case "$OSTYPE" in
    linux*) platform=linux ;;
    darwin*) platform=mac ;;
    *) fail "Unable to determine zap platform for OSTYPE='$OSTYPE'" ;;
    esac
    case "$(uname -m)" in
    arm64) arch=arm64 ;;
    x86_64) arch=x64 ;;
    *) fail "Unable to determine zap architecture for 'uname -m'='$(uname -m)'" ;;
    esac
    local url="https://github.com/project-chip/zap/releases/download/${version}/zap-${platform}-${arch}.zip"

    progress "Installing zap-cli from $url"
    call_impl download_and_extract_zip "$url" "${BUILD_ENV_PATH}/bin" zap-cli
    chmod a+x "${BUILD_ENV_PATH}/bin/zap-cli" # ZipFile.extract() does not handle permissions
    info "ok"
}

function call_impl() { # func ...
    "$PYTHON" "${CHIP_ROOT}/scripts/configure.impl.py" "$@"
}

function check_python() {
    progress "Checking for Python 3"
    if have_binary python3; then
        PYTHON="$(hash -t python3)"
    elif have_binary python; then
        PYTHON="$(hash -t python)"
        local ver="$("$PYTHON" --version)"
        if [[ "$ver" != "Python 3."* ]]; then
            info "need Python 3 but found $ver"
            return 1
        fi
    else
        info "not found"
        return 1
    fi
    info "$PYTHON"
}

function check_binary() { # binary [VAR]
    progress "Checking for $1"
    if ! have_binary "$1"; then
        info "not found"
        return 1
    fi
    local path="$(hash -t "$1")"
    [[ -n "$2" ]] && eval "$2=\$path"
    info "$path"
}

function have_binary() { # binary
    hash "$1" 2>/dev/null
}

function ensure_no_clobber() { # file
    safe_to_clobber "$1" || fail "Won't overwrite file not generated by configure: $1"
}

function safe_to_clobber() { # file
    CONFIGURE_MARKER="Auto-generated by configure, do not edit"
    [[ -s "$1" ]] || return 0
    read -r -n 512 -d '' <"$1" || true
    [[ "${REPLY/$CONFIGURE_MARKER/}" != "$REPLY" ]] && return 0
    return 1
}

function info() { # message
    echo "$*" >&2
}

function progress() { # message
    echo -n "$*... " >&2
}

function fail() { # message
    echo "Error: $*" >&2
    exit 1
}

main "$@"
