#ifndef SIGSUM_POLICY_H_INCLUDED
#define SIGSUM_POLICY_H_INCLUDED

#include <stdbool.h>
#include <stddef.h>

#include "ascii.h"
#include "key-map.h"
#include "merkle.h"
#include "quorum.h"

/* Represents a Sigsum policy (see
   https://git.glasklar.is/sigsum/core/sigsum-go/-/blob/main/doc/policy.md.
*/
struct sigsum_policy
{
  /* The logs and witnesses arrays include the public keys and
     corresponding key hashes. */
  struct sigsum_key_map logs;
  struct sigsum_key_map witnesses;

  struct sigsum_quorum quorum;
};

/* Returns the amount of scratch space needed for verifying the
   policy. Depends on num_witnesses and quorum_stack_size. */
size_t
sigsum_policy_verify_tree_head_itch (const struct sigsum_policy *policy);

/* Verifies that a tree head is signed and cosigned according to the
   given policy. Returns true on success, false on failure. */
bool
sigsum_policy_verify_tree_head (const struct sigsum_policy *policy,
				const struct sigsum_tree_head *tree_head,
				const struct sigsum_hash *log_key_hash,
				const struct sigsum_signature *log_signature,
				size_t num_cosignatures,
				const struct sigsum_cosignature *cosignatures,
				/* If non-NULL, a statically allocated
				   error message is returned on
				   failure. */
				const char **err,
				/* The scratch pointer must point to an area of size at least
				   sigsum_policy_verify_tree_head_itch (policy), and suitably aligned
				   for the bool type. (On most platforms, bool has same size and
				   alignment as a char). */
				void *scratch);

/* Initializes the policy struct, from an ASCII policy file as defined
   in
   https://git.glasklar.is/sigsum/core/sigsum-go/-/blob/main/doc/policy.md.
   Allocates storage for logs, witnesses and quorum. */
bool
sigsum_policy_parse (struct sigsum_policy *policy,
		     size_t size, const char *data,
		     /* If non-NULL, line number and a statically
			allocated error message is returned on
			failure. */
		     struct sigsum_error *err);

/* Clears a policy struct initialized using sigsum_policy_parse, and
   deallocates storage. */
void
sigsum_policy_clear (struct sigsum_policy *policy);

#endif /* SIGSUM_POLICY_H_INCLUDED */
