#!/bin/bash -e

# Copyright (c) 2023-2026 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.

# Check if this script is being sourced; this could be in any shell, not just bash.
if [ -z "$BASH" -o "$BASH_SOURCE" != "$0" ]; then
    echo "configure does not support being sourced" >&2
    return 1
fi

set -o pipefail
shopt -s extglob
unset CDPATH

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         directory to build, absolute or relative to chip root,"
    info "                        eg examples/lighting-app/linux or /my/dir/my/app"
    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 are specified in lower-kebab-case ('-' instead of '_');"
    info "  prefixes like 'chip_' or 'matter_' can be omitted from names. For the full"
    info "  list of build arguments, see the generated build-args.txt 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."
    info ""
    info "Code generation:"
    info "  By default, some code generation will happen at build time using zap-cli."
    info "  If zap-cli is not available on PATH, configure will attempt to download it."
    info "  Alternatively, if a directory called 'zzz_pregenerated' exists at the root"
    info "  of the project or the root of the SDK, pre-generated code from this directory"
    info "  will be used. In this case, build time code generation will be disabled and"
    info "  zap-cli is not required."
    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"
    )
    BUILD_ENV_DEPS_CODEGEN=(
        "${CHIP_ROOT}/scripts/setup/zap.version"
    )

    # Parse global options, process VAR=VALUE style arguments, and collect project options
    BUILD_ENV_DIR=
    PROJECT=
    PROJECT_PATH=
    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
        PROJECT_PATH="$(cd "${CHIP_ROOT}" 2>/dev/null && cd "${PROJECT}" 2>/dev/null && pwd)"
        [[ -n "$PROJECT_PATH" && -r "${PROJECT_PATH}/.gn" ]] || fail "Invalid project '${PROJECT}' (no such directory or missing .gn file)"
    fi

    if [[ -n "$PW_ROOT" ]]; then
        info "WARNING: A Pigweed environment appears to be active, this is usually a misconfiguration."
    fi

    # Check for pre-generated code. CHIP_PREGEN_DIR will be picked up by process_project_args.
    local pregen_dir="zzz_pregenerated"
    if [[ -n "$PROJECT_PATH" && -d "${PROJECT_PATH}/${pregen_dir}" ]]; then
        info "Will use pre-generated code from ${PROJECT}/${pregen_dir}, no zap-cli required."
        export CHIP_PREGEN_DIR="//${pregen_dir}"
    elif [[ -d "${CHIP_ROOT}/${pregen_dir}" ]]; then
        info "Will use pre-generated code from ${pregen_dir}, no zap-cli required."
        export CHIP_PREGEN_DIR="\${chip_root}/${pregen_dir}"
    else
        BUILD_ENV_DEPS+=("${BUILD_ENV_DEPS_CODEGEN[@]}")
        unset CHIP_PREGEN_DIR
    fi

    # 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

    # Check required tools are present
    check_binary gn GN
    check_binary ninja NINJA

    # Create the build environment if necessary
    if ! check_build_env; then
        check_python 3.11
        configure_python_env
        if [[ -z "$CHIP_PREGEN_DIR" ]] && ! 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="${PROJECT_PATH}")

    # Run `gn args` so we know available arguments. The list will drive the
    # mapping of our command line options to GN args. Ostensibly `gn args`
    # requires an existing build directory, but in fact it actually executes
    # the full setup internally anyway (including running things like
    # pkg-config via exec_script). The 'preargs' we pass are chosen to minimize
    # those external dependencies during this pass.
    info "Configuring gn build arguments (see $BUILD_DIR/build-args.txt for supported arguments)"
    touch "${BUILD_DIR}/build.ninja"
    "${gn[@]}" -q args "$BUILD_DIR" \
        --args='import("//build_overrides/chip.gni") import("${chip_root}/scripts/configure.preargs.gni")' \
        --list --json >"${BUILD_DIR}/build-args.json"
    call_impl describe_args "${BUILD_DIR}/build-args.json" >"${BUILD_DIR}/build-args.txt"
    {
        echo "# ${CONFIGURE_MARKER}"
        echo "# project root: ${PROJECT_PATH}"
        echo "import(\"//build_overrides/chip.gni\")"
        call_impl process_project_args "${BUILD_DIR}/build-args.json" "$@"
    } >"${BUILD_DIR}/args.gn"

    # 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"
    # Debian and Ubuntu ship python3 with a broken venv module unless the
    # python3-venv package is installed (https://bugs.launchpad.net/bugs/1290847)
    local withoutpip=() pip="${BUILD_ENV_PATH}/bin/pip"
    if ! "$PYTHON" -m ensurepip --version >/dev/null 2>&1; then
        withoutpip=(--without-pip) pip="${pip}.pyz" # bootstrapped below
    fi
    "$PYTHON" -m venv --clear "${withoutpip[@]}" "$BUILD_ENV_PATH"
    info "$BUILD_ENV_PATH"

    # Download a standalone pip.pyz from pypa.io if necessary
    if [[ -n "$withoutpip" ]]; then
        progress "Bootstrapping pip via pypa.io (venv module is missing ensurepip dependency)"
        call_impl download https://bootstrap.pypa.io/pip/pip.pyz "$pip"
        info "ok"
    fi

    # 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"
    # Ensure pip and wheel are up to date first (using pip.pyz if necessary)
    "${BUILD_ENV_PATH}/bin/python3" "$pip" install --require-virtualenv --quiet --upgrade pip wheel

    # Install build dependencies. Use PEP517 to silence warnings (see https://github.com/pypa/pip/issues/6334)
    "${BUILD_ENV_PATH}/bin/pip" install --require-virtualenv --quiet --use-pep517 \
        -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
    read -r version <"${CHIP_ROOT}/scripts/setup/zap.version"
    local platform="$(uname -sm)" flavor
    case "$platform" in
    Linux\ x86_64) flavor=linux-x64 ;;
    Linux\ arm64) flavor=linux-arm64 ;;
    Linux\ aarch64) flavor=linux-arm64 ;;
    Darwin\ x86_64) flavor=mac-x64 ;;
    Darwin\ arm64) flavor=mac-arm64 ;;
    *) fail "Unable to determine zap flavor for $platform" ;;
    esac
    local url="https://github.com/project-chip/zap/releases/download/${version}/zap-${flavor}.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() { # version
    local required="$1" major="${1%%.*}"
    progress "Checking for Python $required or later"
    if have_binary "python$major"; then
        PYTHON="$(hash -t "python$major")"
    elif have_binary python; then
        PYTHON="$(hash -t python)"
    else
        info "not found"
        return 1
    fi
    if ! "$PYTHON" -c 'import sys; sys.exit(1 if sys.version_info < tuple(map(int,sys.argv[1].split("."))) else 0)' "$required"; then
        info "not found ($PYTHON is $("$PYTHON" --version))"
        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 "$@"
