/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#include "prologue.h"

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

#include "parse.h"
#include "log.h"

char *
joinStrings (const char *const *strings, int count) {
  char *string;
  size_t length = 0;
  size_t lengths[count];

  for (unsigned int index=0; index<count; index+=1) {
    length += lengths[index] = strlen(strings[index]);
  }

  if ((string = malloc(length+1))) {
    char *target = string;

    for (unsigned int index=0; index<count; index+=1) {
      length = lengths[index];
      memcpy(target, strings[index], length);
      target += length;
    }

    *target = 0;
  }

  return string;
}

int
changeStringSetting (char **setting, const char *value) {
  if (value == *setting) return 1;
  char *string;

  if (!value) {
    string = NULL;
  } else if (!(string = strdup(value))) {
    logMallocError();
    return 0;
  }

  if (*setting) free(*setting);
  *setting = string;
  return 1;
}

int
extendStringSetting (char **setting, const char *value, int prepend) {
  if (!value) value = "";

  if (*setting && **setting) {
    if (*value) {
      size_t newSize = strlen(*setting) + 1 + strlen(value) + 1;
      char newSetting[newSize];

      if (prepend) {
        snprintf(newSetting, newSize, "%s%c%s", value, PARAMETER_SEPARATOR_CHARACTER, *setting);
      } else {
        snprintf(newSetting, newSize, "%s%c%s", *setting, PARAMETER_SEPARATOR_CHARACTER, value);
      }

      if (!changeStringSetting(setting, newSetting)) return 0;
    }
  } else if (!changeStringSetting(setting, value)) {
    return 0;
  }

  return 1;
}

void
deallocateStrings (char **array) {
  char **element = array;
  while (*element) free(*element++);
  free(array);
}

char **
splitString (const char *string, char delimiter, int *count) {
  char **array = NULL;

  if (!string) string = "";

  if (string) {
    while (1) {
      const char *start = string;
      int index = 0;

      if (*start) {
        while (1) {
          const char *end = strchr(start, delimiter);
          size_t length = end? (size_t)(end-start): strlen(start);

          if (array) {
            char *element = malloc(length+1);

            if (!(array[index] = element)) {
              logMallocError();
              deallocateStrings(array);
              array = NULL;
              goto done;
            }

            memcpy(element, start, length);
            element[length] = 0;
          }
          index += 1;

          if (!end) break;
          start = end + 1;
        }
      }

      if (array) {
        array[index] = NULL;
        if (count) *count = index;
        break;
      }

      if (!(array = malloc((index + 1) * sizeof(*array)))) {
        logMallocError();
        break;
      }
    }
  }

done:
  if (!array && count) *count = 0;
  return array;
}

int
changeListSetting (char ***list, char **setting, const char *value) {
  char **newList = splitString(value, PARAMETER_SEPARATOR_CHARACTER, NULL);

  if (newList) {
    if (changeStringSetting(setting, value)) {
      char **oldList = *list;
      *list = newList;
      if (oldList) deallocateStrings(oldList);
      return 1;
    }

    deallocateStrings(newList);
  }

  return 0;
}

int
rescaleInteger (int value, int from, int to) {
  return (to * (value + (from / (to * 2)))) / from;
}

int
isInteger (int *value, const char *string) {
  if (*string) {
    char *end;
    long l = strtol(string, &end, 0);

    if (!*end) {
      *value = l;
      return 1;
    }
  }

  return 0;
}

int
isUnsignedInteger (unsigned int *value, const char *string) {
  if (*string) {
    char *end;
    unsigned long l = strtoul(string, &end, 0);

    if (!*end) {
      *value = l;
      return 1;
    }
  }

  return 0;
}

int
isLogLevel (unsigned int *level, const char *string) {
  {
    size_t length = strlen(string);

    for (unsigned int index=0; index<logLevelCount; index+=1) {
      if (strncasecmp(string, logLevelNames[index], length) == 0) {
        *level = index;
        return 1;
      }
    }
  }

  {
    unsigned int value;

    if (isUnsignedInteger(&value, string) && (value < logLevelCount)) {
      *level = value;
      return 1;
    }
  }

  return 0;
}

int
isAbbreviation (const char *actual, const char *supplied) {
  return strncasecmp(actual, supplied, strlen(supplied)) == 0;
}

int
isAbbreviatedPhrase (const char *actual, const char *supplied) {
  while (1) {
    if (!*supplied) return 1;

    if (*supplied == '-') {
      while (*actual != '-') {
        if (!*actual) return 0;
        actual += 1;
      }
    } else if (tolower(*supplied) != tolower(*actual)) {
      return 0;
    }

    actual += 1;
    supplied += 1;
  }
}

int
validateInteger (int *value, const char *string, const int *minimum, const int *maximum) {
  if (*string) {
    int i;

    if (!isInteger(&i, string)) return 0;
    if (minimum && (i < *minimum)) return 0;
    if (maximum && (i > *maximum)) return 0;

    *value = i;
  }

  return 1;
}

int
validateChoiceEx (unsigned int *value, const char *string, const void *choices, size_t size) {
  *value = 0;
  if (!*string) return 1;
  const void *choice = choices;

  while (1) {
    typedef struct {
      const char *name;
    } Entry;

    const Entry *entry = choice;
    const char *name = entry->name;
    if (!name) break;

    if (isAbbreviatedPhrase(name, string)) {
      *value = (choice - choices) / size;
      return 1;
    }

    choice += size;
  }

  return 0;
}

int
validateChoice (unsigned int *value, const char *string, const char *const *choices) {
  return validateChoiceEx(value, string, choices, sizeof(*choices));
}

FlagKeywordPair fkpOnOff     = {.on="on"  , .off="off"  };
FlagKeywordPair fkpTrueFalse = {.on="true", .off="false"};
FlagKeywordPair fkpYesNo     = {.on="yes" , .off="no"   };
FlagKeywordPair fkp10        = {.on="1"   , .off="0"    };

const FlagKeywordPair *const flagKeywordPairs[] = {
  &fkpOnOff, &fkpTrueFalse, &fkpYesNo, &fkp10
};

int
validateFlagKeyword (unsigned int *value, const char *string) {
  static const char **choices = NULL;

  if (!choices) {
    unsigned int count = ARRAY_COUNT(flagKeywordPairs);
    size_t size = ARRAY_SIZE(choices, ((count * 2) + 1));

    if (!(choices = malloc(size))) {
      logMallocError();
      return 0;
    }

    const FlagKeywordPair *const *fkp = flagKeywordPairs;
    const FlagKeywordPair *const *end = fkp + count;
    const char **choice = choices;

    while (fkp < end) {
      *choice++ = (*fkp)->off;
      *choice++ = (*fkp)->on;
      fkp += 1;
    }

    *choice = NULL;
  }

  if (!validateChoice(value, string, choices)) return 0;
  *value %= 2;
  return 1;
}

int
validateFlag (unsigned int *value, const char *string, const FlagKeywordPair *fkp) {
  const char *choices[] = {fkp->off, fkp->on, NULL};
  return validateChoice(value, string, choices);
}

int
validateOnOff (unsigned int *value, const char *string) {
  return validateFlag(value, string, &fkpOnOff);
}

int
validateYesNo (unsigned int *value, const char *string) {
  return validateFlag(value, string, &fkpYesNo);
}

#ifndef NO_FLOAT
int
isFloat (float *value, const char *string) {
  if (*string) {
    char *end;
    double d = strtod(string, &end);

    if (!*end) {
      *value = d;
      return 1;
    }
  }

  return 0;
}

int
validateFloat (float *value, const char *string, const float *minimum, const float *maximum) {
  if (*string) {
    float f;

    if (!isFloat(&f, string)) return 0;
    if (minimum && (f < *minimum)) return 0;
    if (maximum && (f > *maximum)) return 0;

    *value = f;
  }

  return 1;
}
#endif /* NO_FLOAT */

#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
#include <pwd.h>
#include <grp.h>

int
validateUser (uid_t *value, const char *string, gid_t *group) {
  {
    int integer = geteuid();
    static const int minimum = 0;

    if (validateInteger(&integer, string, &minimum, NULL)) {
      *value = integer;

      if (group) {
        struct passwd *user = getpwuid(*value);
        *group = user? user->pw_gid: 0;
      }

      return 1;
    }
  }

  {
    struct passwd *user = getpwnam(string);

    if (user) {
      *value = user->pw_uid;
      if (group) *group = user->pw_gid;
      return 1;
    }
  }

  return 0;
}

int
validateGroup (gid_t *value, const char *string) {
  {
    int integer = geteuid();
    static const int minimum = 0;

    if (validateInteger(&integer, string, &minimum, NULL)) {
      *value = integer;
      return 1;
    }
  }

  {
    struct group *group = getgrnam(string);

    if (group) {
      *value = group->gr_gid;
      return 1;
    }
  }

  return 0;
}
#endif /* defined(HAVE_PWD_H) && defined(HAVE_GRP_H) */

int
hasQualifier (const char **identifier, const char *qualifier) {
  const char *delimiter = strchr(*identifier, PARAMETER_QUALIFIER_CHARACTER);
  if (!delimiter) return 0;

  size_t count = delimiter - *identifier;
  if (memchr(*identifier, PATH_SEPARATOR_CHARACTER, count)) return 0;

  if (qualifier) {
    if (count != strlen(qualifier)) return 0;
    if (strncasecmp(*identifier, qualifier, count) != 0) return 0;
  }

  *identifier += count + 1;
  return 1;
}

int
hasNoQualifier (const char *identifier) {
  return !hasQualifier(&identifier, NULL);
}

static int
parseParameters (
  char **values,
  const char *const *names,
  const char *qualifier,
  const char *parameters
) {
  if (parameters && *parameters) {
    const char *parameter = parameters;

    while (1) {
      const char *parameterEnd = strchr(parameter, PARAMETER_SEPARATOR_CHARACTER);
      int done = !parameterEnd;

      if (done) parameterEnd = parameter + strlen(parameter);
      int parameterLength = parameterEnd - parameter;

      if (parameterLength > 0) {
        const char *value = memchr(parameter, PARAMETER_ASSIGNMENT_CHARACTER, parameterLength);

        if (!value) {
          logMessage(LOG_WARNING, "%s: %.*s",
                     gettext("missing parameter value"),
                     parameterLength, parameter);
          goto NEXT_PARAMETER;
        }

        {
          const char *name = parameter;
          size_t nameLength = value++ - name;
          size_t valueLength = parameterEnd - value;
          int isEligible = 1;

          if (qualifier) {
            const char *delimiter = memchr(name, PARAMETER_QUALIFIER_CHARACTER, nameLength);

            if (delimiter) {
              size_t qualifierLength = delimiter - name;
              size_t nameAdjustment = qualifierLength + 1;

              name += nameAdjustment;
              nameLength -= nameAdjustment;
              isEligible = 0;

              if (!qualifierLength) {
                logMessage(LOG_WARNING, "%s: %.*s",
                           gettext("missing parameter qualifier"),
                           parameterLength, parameter);
                goto NEXT_PARAMETER;
              }

              if ((qualifierLength == strlen(qualifier)) &&
                  (memcmp(parameter, qualifier, qualifierLength) == 0)) {
                isEligible = 1;
              }
            }
          }

          if (!nameLength) {
            logMessage(LOG_WARNING, "%s: %.*s",
                       gettext("missing parameter name"),
                       parameterLength, parameter);
            goto NEXT_PARAMETER;
          }

          if (isEligible) {
            unsigned int index = 0;

            while (names[index]) {
              if (strncasecmp(name, names[index], nameLength) == 0) {
                char *newValue = malloc(valueLength + 1);

                if (!newValue) {
                  logMallocError();
                  return 0;
                }

                memcpy(newValue, value, valueLength);
                newValue[valueLength] = 0;

                free(values[index]);
                values[index] = newValue;
                goto NEXT_PARAMETER;
              }

              index += 1;
            }

            logMessage(LOG_WARNING, "%s: %.*s",
                       gettext("unsupported parameter"),
                       parameterLength, parameter);
            goto NEXT_PARAMETER;
          }
        }
      }

    NEXT_PARAMETER:
      if (done) break;
      parameter = parameterEnd + 1;
    }
  }

  return 1;
}

char **
getParameters (const char *const *names, const char *qualifier, const char *parameters) {
  if (!names) {
    static const char *const noNames[] = {NULL};
    names = noNames;
  }

  {
    char **values;
    unsigned int count = 0;
    while (names[count]) count += 1;

    if ((values = malloc((count + 1) * sizeof(*values)))) {
      unsigned int index = 0;

      while (index < count) {
        if (!(values[index] = strdup(""))) {
          logMallocError();
          break;
        }

        index += 1;
      }

      if (index == count) {
        values[index] = NULL;
        if (parseParameters(values, names, qualifier, parameters)) return values;
      }

      deallocateStrings(values);
    } else {
      logMallocError();
    }
  }

  return NULL;
}

void
logParameters (const char *const *names, char **values, const char *description) {
  if (names && values) {
    while (*names) {
      logMessage(LOG_INFO, "%s: %s=%s", description, *names, *values);
      ++names;
      ++values;
    }
  }
}
