// SPDX-License-Identifier: GPL-2.0-only
/*
 *  ppm/include/ppm/build.h
 *
 *  Source-from-build pipeline. When a manifest carries a [build]
 *  section it is treated as a *derivation*: a deterministic function
 *  from (source, dependencies, system, script) to an output directory
 *  tree. The output is content-addressed by a hash of those inputs,
 *  not by the hash of the produced bytes (which may vary across
 *  builds even when the inputs are identical, e.g. timestamps).
 *
 *  Copyright (C) 2026 Project Tick
 */

#ifndef PPM_BUILD_H
#define PPM_BUILD_H

#include <ppm/error.h>
#include <ppm/manifest.h>
#include <ppm/store.h>
#include <ppm/crypto.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Compute the deterministic output hash for a build, given the
 * resolved build-time dependency hashes. The hash covers:
 *   - package name + version
 *   - source URL + source SHA-512
 *   - target system (manifest.build.system) or detected system
 *   - the script body verbatim
 *   - the SHA-512 of each build-dep, in sorted-by-name order
 *
 * Same inputs ⇒ same output hash. This is the path under which the
 * build artefacts will be deposited in the store.
 */
ppm_error_t ppm_build_output_hash(const ppm_manifest_t *m,
                                  const char *const   *dep_names,
                                  const ppm_sha512_t  *dep_hashes,
                                  size_t                dep_count,
                                  ppm_sha512_t        *out);

/*
 * Execute the build described by `m`:
 *   1. Compute the output hash.
 *   2. If the store already has it, return PPM_OK (cache hit).
 *   3. Otherwise: download the source tarball, extract it into a
 *      staging directory, run the script under /bin/sh -e with
 *      $src/$out/$PATH wired up, then move $out into the store under
 *      the computed hash.
 *
 * `dep_paths`, if non-NULL, points to `dep_count` absolute paths to
 * already-built build-time deps (one per entry in `dep_names`). These
 * are prepended to PATH so the script can call them.
 *
 * Returns the canonical output hash via `out_hash`. The same value is
 * usable with `ppm_store_path` and `ppm_store_has`.
 */
ppm_error_t ppm_build_run(ppm_store_t          *store,
                          const ppm_manifest_t *m,
                          const char *const    *dep_names,
                          const ppm_sha512_t   *dep_hashes,
                          const char *const    *dep_paths,
                          size_t                 dep_count,
                          ppm_sha512_t          *out_hash);

#ifdef __cplusplus
}
#endif

#endif /* PPM_BUILD_H */
