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

#include "string.h"

int32_t stringHandlebarsBuffer(char *source,
  stringhandlebarvariable_t *variables, int32_t variableCount, char *buffer
) {
  
  int32_t i, l, n;
  char c;
  char keyBuffer[STRING_HANDLEBAR_KEY_MAXLENGTH];
  stringhandlebarvariable_t *variable;

  // Start two counters. I holds source index, L holds target index.
  i = 0;
  l = 0;

  while(true) {
    c = source[i];
    if(c == '\0') break;// Break on end of string.

    // Look for {{, if not {{ then just treat as normal string.
    if(c != '{' || source[i + 1] != '{') {
      buffer[l] = c;
      i++;
      l++;
      continue;
    }

    //Ignore those two chars
    i += 2;

    // Skip space(s)
    while(true) {
      c = source[i];
      if(c != ' ') break;
      i++;
    }

    // Get the key name
    n = 0;// Will hold the index within keyBuffer to copy chars into.
    while(true) {
      c = source[i];

      // Don't overflow
      if(c == '\0') break;
      
      // Skip spaces
      if(c == ' ') {
        i++;
        continue;
      }

      // Handle end of key
      if(c == '}') {
        i++;
        if(source[i] == '}') i++;// For }} then skip the second }
        break;
      }

      // Add to buffer.
      keyBuffer[n] = c;
      n++;
      i++;
    }

    // Seal the keyBuffer string
    keyBuffer[n] = '\0';

    // Now check each variable for a match.
    for(n = 0; n < variableCount; n++) {
      variable = variables + n;
      if(strcmp(keyBuffer, variable->key) != 0) continue;// Does the key match?

      // Begin copying the variables' value into the string.
      n = 0;
      while(true) {
        if(variable->value[n] == '\0') break;// Handle end of variable value
        buffer[l] = variable->value[n];
        l++;
        n++;
      }
      // We found the value, so break.
      break;
    }

    // Continue looking for next {{ variable }}...
  }

  // Buffer has been fully cloned, seal the string.
  buffer[l] = '\0';

  // Return the count of chars we wrote to the buffer. -1 due to null term.
  return l - 1;
}

void stringStackInit(stringstack_t *stack) {
  stack->size = 0;
}

void stringStackPush(stringstack_t *stack, char *string) {
  size_t offset = stack->size * STRING_STACK_STRING_SIZE;
  arrayCopy(
    sizeof(char), string,
    (int32_t)strlen(string) + 1,
    stack->strings + offset
  );
  stack->strings[stack->size] = stack->buffer + offset;
  stack->size++;
}

void stringStackPop(stringstack_t *stack) {
  stack->size -= 1;
}