#ifndef SIGSUM_POLICY_INTERNAL_H_INCLUDED
#define SIGSUM_POLICY_INTERNAL_H_INCLUDED

#include <stdint.h>

#include "ascii.h"

/* When parsing an ASCII policy, names are represented as a list of
   definitions, see struct sigsum_policy_def below. Each definition
   refers to either a witness, a group, or the predefined name
   "none". */
enum sigsum_policy_def_type
  {
    SIGSUM_POLICY_DEF_NONE,
    SIGSUM_POLICY_DEF_WITNESS,
    SIGSUM_POLICY_DEF_GROUP,
  };

/* Represents a k-of-n group. Must have 1 <= threshold <=
   num_members. */
struct sigsum_policy_group
{
  size_t num_members;
  /* Elements are indices of *preceding* entries in the list of
     definitions. */
  size_t *members;
  size_t threshold;
};

/* Represent the definition of a name. */
struct sigsum_policy_def
{
  struct sigsum_buffer name;
  size_t bytecode_size;
  bool is_referenced;

  enum sigsum_policy_def_type type;
  union {
    /* For type SIGSUM_POLICY_DEF_WITNESS, index in witness list. */
    size_t witness_index;
    /* For type SIGSUM_POLICY_DEF_GROUP. */
    struct sigsum_policy_group group;
  };
};

/* Set bytecode size, and sorts members by size, if the definition is
   a group. */
void
_sigsum_bytecode_size (const struct sigsum_policy_def *defs,
		       struct sigsum_policy_def *def);

void
_sigsum_bytecode_compile (uint8_t *bytecode, const struct sigsum_policy_def *defs,
			  const struct sigsum_policy_def *def);

/* Computes needed stack size. Returns (size_t) -1 if byte code is invalid. */
size_t
_sigsum_bytecode_stack (size_t n, const uint8_t *bytecode);


#endif /* SIGSUM_POLICY_INTERNAL_H_INCLUDED */
