// Copyright (c) 2021 Dominic Masters
// 
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#pragma once
#include "../libs.h"
#include "array.h"

#define STRING_HANDLEBAR_KEY_MAXLENGTH 32

#define STRING_STACK_STRING_SIZE 256
#define STRING_STACK_STRING_COUNT 128
#define STRING_STACK_BUFFER STRING_STACK_STRING_SIZE * STRING_STACK_STRING_COUNT

/** Representation of a String Handlebar Variable */
typedef struct {
  /** The key to use to replace in the source */
  char *key;
  /** The value to replace it with */
  char *value;
} stringhandlebarvariable_t;

/** Definition of a string stack to push and pop strings from. */
typedef struct {
  /** Raw char buffer, for holding strings */
  char buffer[STRING_STACK_BUFFER];
  /** Strings themselves */
  char *strings[STRING_STACK_STRING_COUNT];
  /** How many strings are on the stack */
  int32_t size;
} stringstack_t;

/**
 * Replaces handlebars within the string with items from the list of variables.
 * Output of replacement is stored in the buffer provided. Handlebars within the
 * string should be in the format of; "{{ key }}", spaces within the bars will
 * be skipped. Variable keys cannot exceed STRING_HANDLEBAR_KEY_MAXLENGTH in
 * length.
 * 
 * @param string String to parse.
 * @param variables Variables to use in the parsing.
 * @param variableCount How many variables in the array.
 * @param buffer Buffer to write characters in to.
 * @return The count of characters that were written to the buffer.
 */
int32_t stringHandlebarsBuffer(char *source,
  stringhandlebarvariable_t *variables, int32_t variableCount, char *buffer
);

/**
 * Initializes a string stack for pushing strings on to.
 * @param stack Stack to initialize.
 */
void stringStackInit(stringstack_t *stack);

/**
 * Push a string onto the stack. The source string will be copied so you can
 * change the original pointer after this push operation.
 * @param stack Stack to push onto.
 * @param string String to copy and push.
 */
void stringStackPush(stringstack_t *stack, char *string);

/**
 * Pop an element off the end of a string stack.
 * @param stack Stack to pop from.
 */
void stringStackPop(stringstack_t *stack);