#include <ctype.h>
#include <stdlib.h>
#include <string.h>

#include "Error.h"

#include "appglobal.h"
#include "log.h"
#include "msgtrandyn.h"

/* Not sure whether strlen(NULL) is valid, so just in case */
#define MTD_STRLEN(s) ((s) ? strlen(s) : (size_t) 0)

char *MsgTransDyn_LookupPS(const msgtrans_filedesc *fd, const char *token,
                           const char *p0, const char *p1,
                           const char *p2, const char *p3,
                           BOOL report)
{
  char *buffer = NULL;
  int buflen = 0;
  os_error *e;
  char *bufout = buffer;

  e = MessageTrans_Lookup((msgtrans_filedesc *) fd,
                          (char *) token, &bufout, &buflen,
                          (char *) p0, (char *) p1,
                          (char *) p2, (char *) p3);
  if (e)
  {
    if (report)
      Error_Check(e);
    return NULL;
  }
  /* buffer = malloc(buflen += 8); */
  buffer = malloc(buflen += 1 + MTD_STRLEN(p0) + MTD_STRLEN(p1)
           + MTD_STRLEN(p2) + MTD_STRLEN(p3));
  if (!buffer)
  {
    Error_Report(0, MSG_NOMEM);
    return NULL;
  }
  /* Note this time we want result terminated */
  if (Error_Check(MsgTrans_LookupPS((msgtrans_filedesc *) fd, (char *) token,
                                    buffer, buflen,
                                    (char *) p0, (char *) p1,
                                    (char *) p2, (char *) p3)))
  {
    free(buffer);
    return NULL;
  }
  return buffer;
}

int MsgTransDyn_LookupInt(const msgtrans_filedesc *fd, const char *token,
                          BOOL report, int def)
{
  int result;
  char *str = MsgTransDyn_Lookup(fd, token, report);

  if (!str || !str[0])
  {
    free(str);
    return def;
  }
  /* If string isn't a valid number, tough */
  result = atoi(str);
  free(str);
  return result;
}

static BOOL MsgTransDyn_str_to_bool(const char *str, BOOL def)
{
  BOOL result = def;

  switch (tolower(str[0]))
  {
    case 'y': case 't': case '1':
      result = TRUE;
      break;
    case 'n': case 'f': case '0':
      result = FALSE;
      break;
    case 'o':
      if (tolower(str[1]) == 'n')
        result = TRUE;
      else if (tolower(str[1]) == 'f' && tolower(str[2]) == 'f')
        result = FALSE;
      break;
  }
  return result;
}

BOOL MsgTransDyn_LookupBool(const msgtrans_filedesc *fd, const char *token,
                            BOOL report, BOOL def)
{
  BOOL result = def;
  char *str = MsgTransDyn_Lookup(fd, token, report);

  if (!str || !str[0])
  {
    free(str);
    return def;
  }
  result = MsgTransDyn_str_to_bool(str, FALSE);
  free(str);
  return result;
}

control_optional_t MsgTransDyn_LookupOptional(const msgtrans_filedesc *fd,
                                              const char *token)
{
  control_optional_t result = control_NotOptional;
  char *str = MsgTransDyn_Lookup(fd, token, FALSE);

  if (!str || !str[0])
  {
    free(str);
    return control_NotOptional;
  }
  if (MsgTransDyn_str_to_bool(str, TRUE))
    result = control_OptionalOn;
  else
    result = control_OptionalOff;
  free(str);
  return result;
}
