// SPDX-License-Identifier: GPL-2.0-only
/*
 *  ppm/include/ppm/store.h
 *
 *  Copyright (C) 2026 Project Tick
 */

#ifndef PPM_STORE_H
#define PPM_STORE_H

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

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Store — the content-addressed on-disk artifact cache.
 *
 * Layout:
 *   <root>/sha512/<hex[0:2]>/<hex>/      unpacked package tree
 *   <root>/tmp/<txn-id>/                 staging area for in-flight installs
 *   <root>/profiles/<name>/current       symlink to active generation
 *
 * Operations are atomic: a package either fully materialises under its
 * final SHA-512 path or leaves no trace.
 */

typedef struct ppm_store ppm_store_t;

ppm_error_t ppm_store_open (const char *root, ppm_store_t **out);
void        ppm_store_close(ppm_store_t *store);

/* True iff an unpacked tree for `hash` already exists in the store. */
bool ppm_store_has(const ppm_store_t *store, const ppm_sha512_t *hash);

/* Returns the absolute filesystem path for a stored object. Caller frees. */
ppm_error_t ppm_store_path(const ppm_store_t *store,
                           const ppm_sha512_t *hash,
                           char **out_path);

/*
 * Ingest a tarball from `tarball_path`, verifying its SHA-512 against
 * `expected`. On success, the unpacked tree is reachable via ppm_store_path().
 */
ppm_error_t ppm_store_ingest_tarball(ppm_store_t        *store,
                                     const char         *tarball_path,
                                     const ppm_sha512_t *expected);

/*
 * Move an already-prepared directory tree into the store under the
 * given hash. Used by the builder to deposit build outputs: the caller
 * is responsible for choosing `hash` (typically a deterministic
 * derivation hash, not the tree's content hash). On success the tree
 * is renamed atomically into `sha512/<hh>/<hex>/`. If an object with
 * that hash already exists, `dir_path` is removed and we return PPM_OK
 * — i.e. concurrent builds are race-safe.
 */
ppm_error_t ppm_store_ingest_dir(ppm_store_t        *store,
                                 const char         *dir_path,
                                 const ppm_sha512_t *hash);

/* Re-hash every object under the store and report mismatches. */
ppm_error_t ppm_store_verify(ppm_store_t *store, int *out_bad_count);

#ifdef __cplusplus
}
#endif

#endif /* PPM_STORE_H */
