/*
 * 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 "log.h"
#include "strfmt.h"
#include "ktb.h"
#include "ktb_internal.h"
#include "ktb_inspect.h"

typedef struct {
  KeyTable *table;
  const KeyContext *ctx;
  const char *path;
} KeyTableAuditorParameters;

#define KEY_TABLE_AUDITOR(name) int name (const KeyTableAuditorParameters *kta)
typedef KEY_TABLE_AUDITOR(KeyTableAuditor);

static void
reportKeyTableAudit (const char *audit) {
  logMessage(LOG_WARNING, "%s", audit);
}

static
STR_BEGIN_FORMATTER(
  formatKeyTableAuditPrefix,
  const KeyTableAuditorParameters *kta,
  const char *problem
)
  if (kta->path) STR_PRINTF("%s: ", kta->path);
  STR_PRINTF("%s", problem);
  if (kta->ctx) STR_PRINTF(": %" PRIws, kta->ctx->name);
STR_END_FORMATTER

static KEY_TABLE_AUDITOR(reportKeyContextProblems) {
  int ok = 1;

  if (kta->ctx->name && !kta->ctx->isSpecial) {
    const char *problem = NULL;

    if (!kta->ctx->isDefined) {
      problem = "undefined context";
    } else if (!kta->ctx->isReferenced) {
      problem = "unreferenced context";
    } else if (!(kta->ctx->keyBindings.count ||
                 kta->ctx->mappedKeys.count ||
                 kta->ctx->mappedKeys.superimpose ||
                 kta->ctx->hotkeys.count)) {
      problem = "empty context";
    }

    if (problem) {
      ok = 0;

      char audit[0X100];
      STR_BEGIN(audit, sizeof(audit));

      STR_FORMAT(formatKeyTableAuditPrefix, kta, problem);

      STR_END;
      reportKeyTableAudit(audit);
    }
  }

  return ok;
}

static KEY_TABLE_AUDITOR(reportDuplicateKeyBindings) {
  int ok = 1;
  const KeyBinding *binding = kta->ctx->keyBindings.table;
  const KeyBinding *end = binding + kta->ctx->keyBindings.count;

  while (binding < end) {
    if (binding->flags & KBF_DUPLICATE) {
      ok = 0;

      char audit[0X100];
      STR_BEGIN(audit, sizeof(audit));

      STR_FORMAT(formatKeyTableAuditPrefix, kta, "duplicate key binding");
      STR_PRINTF(": ");
      STR_FORMAT(formatKeyCombination, kta->table, &binding->keyCombination);

      STR_END;
      reportKeyTableAudit(audit);
    }

    binding += 1;
  }

  return ok;
}

static void
reportKeyProblem (const KeyTableAuditorParameters *kta, const KeyValue *key, const char *problem) {
  char audit[0X100];
  STR_BEGIN(audit, sizeof(audit));

  STR_FORMAT(formatKeyTableAuditPrefix, kta, problem);
  STR_PRINTF(": ");
  STR_FORMAT(formatKeyName, kta->table, key);

  STR_END;
  reportKeyTableAudit(audit);
}

static KEY_TABLE_AUDITOR(reportDuplicateHotkeys) {
  int ok = 1;
  const HotkeyEntry *hotkey = kta->ctx->hotkeys.table;
  const HotkeyEntry *end = hotkey + kta->ctx->hotkeys.count;

  while (hotkey < end) {
    if (hotkey->flags & HKF_DUPLICATE) {
      ok = 0;
      reportKeyProblem(kta, &hotkey->keyValue, "duplicate hotkey");
    }

    hotkey += 1;
  }

  return ok;
}

static KEY_TABLE_AUDITOR(reportDuplicateMappedKeys) {
  int ok = 1;
  const MappedKeyEntry *map = kta->ctx->mappedKeys.table;
  const MappedKeyEntry *end = map + kta->ctx->mappedKeys.count;

  while (map < end) {
    if (map->flags & MKF_DUPLICATE) {
      ok = 0;
      reportKeyProblem(kta, &map->keyValue, "duplicate mapped key");
    }

    map += 1;
  }

  return ok;
}

int
auditKeyTable (KeyTable *table, const char *path) {
  int ok = 1;

  for (unsigned int context=0; context<table->keyContexts.count; context+=1) {
    const KeyContext *ctx = getKeyContext(table, context);

    if (ctx) {
      static KeyTableAuditor *const auditors[] = {
        reportKeyContextProblems,
        reportDuplicateKeyBindings,
        reportDuplicateHotkeys,
        reportDuplicateMappedKeys,
        NULL
      };

      const KeyTableAuditorParameters kta = {
        .table = table,
        .ctx = ctx,
        .path = path
      };

      for (
        KeyTableAuditor *const *auditor=auditors;
        *auditor!=NULL; auditor+=1
      ) {
        if (!(*auditor)(&kta)) ok = 0;
      }
    }
  }

  return ok;
}
