#ifndef SIGSUM_POLICY_H_INCLUDED
#define SIGSUM_POLICY_H_INCLUDED

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

#include "crypto.h"
#include "merkle.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, and the arrays MUST be sorted
     lexicographically by hash. */
  size_t num_logs;
  const struct sigsum_key_with_hash *logs;
  size_t num_witnesses;
  const struct sigsum_key_with_hash *witnesses;

  /* The policy quorum is represented using bytecode for the stack
     machine defined in doc/quorum-bytecode.md. */
  size_t quorum_length;
  const uint8_t *quorum_bytecode;

  /* The stack size required for evaluating the quorum. */
  size_t quorum_stack_size;
};

/* 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);

struct sigsum_error
{
  const char *msg;
  size_t line;
};

/* 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,
		     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 */
