/*
htop - PCPDynamicScreen.c
(C) 2022 Sohaib Mohammed
(C) 2022-2023 htop dev team
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

#include "config.h" // IWYU pragma: keep

#include "pcp/PCPDynamicScreen.h"

#include <ctype.h>
#include <dirent.h>
#include <stdbool.h>
#include <pcp/pmapi.h>

#include "AvailableColumnsPanel.h"
#include "Macros.h"
#include "Platform.h"
#include "Settings.h"
#include "XUtils.h"

#include "pcp/InDomTable.h"
#include "pcp/PCPDynamicColumn.h"


static char* formatFields(PCPDynamicScreen* screen) {
   char* columns = strdup("");

   for (size_t j = 0; j < screen->totalColumns; j++) {
      const PCPDynamicColumn* column = screen->columns[j];
      if (column->super.enabled == false)
         continue;
      char* prefix = columns;
      xAsprintf(&columns, "%s Dynamic(%s)", prefix, column->super.name);
      free(prefix);
   }

   return columns;
}

static void PCPDynamicScreens_appendDynamicColumns(PCPDynamicScreens* screens, PCPDynamicColumns* columns) {
   for (size_t i = 0; i < screens->count; i++) {
      PCPDynamicScreen* screen = Hashtable_get(screens->table, i);
      if (!screen)
         return;

      /* setup default fields (columns) based on configuration */
      for (size_t j = 0; j < screen->totalColumns; j++) {
         PCPDynamicColumn* column = screen->columns[j];

         column->id = columns->offset + columns->cursor;
         columns->cursor++;
         Platform_addMetric(column->id, column->metricName);

         size_t id = columns->count + LAST_PROCESSFIELD;
         Hashtable_put(columns->table, id, column);
         columns->count++;

         if (j == 0) {
            const pmDesc* desc = Metric_desc(column->id);
            assert(desc->indom != PM_INDOM_NULL);
            screen->indom = desc->indom;
            screen->key = column->id;
         }
      }
      screen->super.columnKeys = formatFields(screen);
   }
}

static PCPDynamicColumn* PCPDynamicScreen_lookupMetric(PCPDynamicScreen* screen, const char* name) {
   PCPDynamicColumn* column = NULL;
   if ((strlen(name) + strlen(screen->super.name) + 1) >= sizeof(column->super.name)) /* colon */
      return NULL;

   char* metricName = NULL;
   xAsprintf(&metricName, "htop.screen.%s.%s", screen->super.name, name);

   for (size_t i = 0; i < screen->totalColumns; i++) {
      column = screen->columns[i];
      if (String_eq(column->metricName, metricName)) {
         free(metricName);
         return column;
      }
   }

   /* not an existing column in this screen - create it and add to the list */
   column = xCalloc(1, sizeof(PCPDynamicColumn));
   xSnprintf(column->super.name, sizeof(column->super.name), "%s:%s", screen->super.name, name);
   column->super.table = &screen->table->super;
   column->metricName = metricName;
   column->super.enabled = true;

   size_t n = screen->totalColumns + 1;
   screen->columns = xReallocArray(screen->columns, n, sizeof(PCPDynamicColumn*));
   screen->columns[n - 1] = column;
   screen->totalColumns = n;

   return column;
}

static void PCPDynamicScreen_parseColumn(PCPDynamicScreen* screen, const char* path, unsigned int line, char* key, char* value) {
   char* p = strchr(key, '.');
   if (!p) {
      return;
   }

   *p++ = '\0'; /* end the name, p is now the attribute, e.g. 'label' */

   /* lookup a dynamic column with this name, else create */
   PCPDynamicColumn* column = PCPDynamicScreen_lookupMetric(screen, key);
   if (!column) {
      return;
   }

   if (String_eq(p, "metric")) {
      char* error = NULL;
      if (pmRegisterDerivedMetric(column->metricName, value, &error) < 0) {
         char* note = NULL;
         xAsprintf(
            &note,
            "%s: failed to parse expression in %s at line %u\n%s\n",
            pmGetProgname(), path, line, error
         );

         errno = EINVAL;
         CRT_fatalError(note);
         free(note);

         free(error);
      }

      /* pmLookupText - add optional metric help text */
      if (!column->super.description && !column->instances) {
         Metric_lookupText(value, &column->super.description);
      }
   } else {
      /* this is a property of a dynamic column - the column expression */
      /* may not have been observed yet; i.e. we allow for any ordering */

      if (String_eq(p, "caption")) {
         free_and_xStrdup(&column->super.caption, value);
      } else if (String_eq(p, "heading")) {
         free_and_xStrdup(&column->super.heading, value);
      } else if (String_eq(p, "description")) {
         free_and_xStrdup(&column->super.description, value);
      } else if (String_eq(p, "width")) {
         column->width = strtoul(value, NULL, 10);
      } else if (String_eq(p, "format")) {
         free_and_xStrdup(&column->format, value);
      } else if (String_eq(p, "instances")) {
         column->instances = false;
         if (String_eq(value, "True") || String_eq(value, "true")) {
            column->instances = true;
         }
         free_and_xStrdup(&column->super.description, screen->super.caption);
      } else if (String_eq(p, "default")) { /* displayed by default */
         column->defaultEnabled = column->super.enabled = true;
         if (String_eq(value, "False") || String_eq(value, "false")) {
            column->defaultEnabled = column->super.enabled = false;
         }
      }
   }
}

static bool PCPDynamicScreen_validateScreenName(char* key, const char* path, unsigned int line) {
   char* p = key;
   char* end = strrchr(key, ']');

   if (end) {
      *end = '\0';
   } else {
      fprintf(stderr,
            "%s: no closing brace on screen name at %s line %u\n\"%s\"",
            pmGetProgname(), path, line, key);
      return false;
   }

   while (*p) {
      if (p == key) {
         if (!isalpha(*p) && *p != '_')
            break;
      } else {
         if (!isalnum(*p) && *p != '_')
            break;
      }
      p++;
   }
   if (*p != '\0') { /* badness */
      fprintf(stderr,
            "%s: invalid screen name at %s line %u\n\"%s\"",
            pmGetProgname(), path, line, key);
      return false;
   }
   return true;
}

/* Ensure a screen name has not been defined previously */
static bool PCPDynamicScreen_uniqueName(char* key, PCPDynamicScreens* screens) {
   return !DynamicScreen_search(screens->table, key, NULL);
}

static PCPDynamicScreen* PCPDynamicScreen_new(PCPDynamicScreens* screens, const char* name) {
   PCPDynamicScreen* screen = xCalloc(1, sizeof(*screen));
   String_safeStrncpy(screen->super.name, name, sizeof(screen->super.name));
   screen->defaultEnabled = true;

   size_t id = screens->count;
   Hashtable_put(screens->table, id, screen);
   screens->count++;

   return screen;
}

static void PCPDynamicScreen_parseFile(PCPDynamicScreens* screens, const char* path) {
   FILE* file = fopen(path, "r");
   if (!file)
      return;

   PCPDynamicScreen* screen = NULL;
   unsigned int lineno = 0;
   bool ok = true;
   for (;;) {
      char* line = String_readLine(file);
      if (!line)
         break;
      lineno++;

      /* cleanup whitespace, skip comment lines */
      char* trimmed = String_trim(line);
      free(line);
      if (!trimmed || !trimmed[0] || trimmed[0] == '#') {
         free(trimmed);
         continue;
      }

      size_t n;
      char** config = String_split(trimmed, '=', &n);
      free(trimmed);
      if (config == NULL)
         continue;

      char* key = String_trim(config[0]);
      char* value = n > 1 ? String_trim(config[1]) : NULL;
      if (key[0] == '[') {  /* new section name - i.e. new screen */
         ok = PCPDynamicScreen_validateScreenName(key + 1, path, lineno);
         if (ok)
            ok = PCPDynamicScreen_uniqueName(key + 1, screens);
         if (ok)
            screen = PCPDynamicScreen_new(screens, key + 1);
         if (pmDebugOptions.appl0)
            fprintf(stderr, "[%s] screen: %s\n", path, key + 1);
      } else if (!ok) {
         ;  /* skip this one, we're looking for a new header */
      } else if (!value || !screen) {
         ;  /* skip this one as we always need value strings */
      } else if (String_eq(key, "heading")) {
         free_and_xStrdup(&screen->super.heading, value);
      } else if (String_eq(key, "caption")) {
         free_and_xStrdup(&screen->super.caption, value);
      } else if (String_eq(key, "sortKey")) {
         free_and_xStrdup(&screen->super.sortKey, value);
      } else if (String_eq(key, "sortDirection")) {
         screen->super.direction = strtoul(value, NULL, 10);
      } else if (String_eq(key, "default") || String_eq(key, "enabled")) {
         if (String_eq(value, "False") || String_eq(value, "false"))
            screen->defaultEnabled = false;
         else if (String_eq(value, "True") || String_eq(value, "true"))
            screen->defaultEnabled = true; /* also default */
      } else {
         PCPDynamicScreen_parseColumn(screen, path, lineno, key, value);
      }
      String_freeArray(config);
      free(value);
      free(key);
   }
   fclose(file);
}

static void PCPDynamicScreen_scanDir(PCPDynamicScreens* screens, char* path) {
   DIR* dir = opendir(path);
   if (!dir)
      return;

   struct dirent* dirent;
   while ((dirent = readdir(dir)) != NULL) {
      if (dirent->d_name[0] == '.')
         continue;

      char* file = String_cat(path, dirent->d_name);
      PCPDynamicScreen_parseFile(screens, file);
      free(file);
   }
   closedir(dir);
}

void PCPDynamicScreens_init(PCPDynamicScreens* screens, PCPDynamicColumns* columns) {
   const char* share = pmGetConfig("PCP_SHARE_DIR");
   const char* sysconf = pmGetConfig("PCP_SYSCONF_DIR");
   const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
   const char* override = getenv("PCP_HTOP_DIR");
   const char* home = getenv("HOME");
   char* path;

   screens->table = Hashtable_new(0, true);

   /* developer paths - PCP_HTOP_DIR=./pcp ./pcp-htop */
   if (override) {
      path = String_cat(override, "/screens/");
      PCPDynamicScreen_scanDir(screens, path);
      free(path);
   }

   /* next, search in home directory alongside htoprc */
   if (xdgConfigHome)
      path = String_cat(xdgConfigHome, "/htop/screens/");
   else if (home)
      path = String_cat(home, CONFIGDIR "/htop/screens/");
   else
      path = NULL;
   if (path) {
      PCPDynamicScreen_scanDir(screens, path);
      free(path);
   }

   /* next, search in the system screens directory */
   path = String_cat(sysconf, "/htop/screens/");
   PCPDynamicScreen_scanDir(screens, path);
   free(path);

   /* next, try the readonly system screens directory */
   path = String_cat(share, "/htop/screens/");
   PCPDynamicScreen_scanDir(screens, path);
   free(path);

   /* establish internal metric identifier mappings */
   PCPDynamicScreens_appendDynamicColumns(screens, columns);
}

static void PCPDynamicScreen_done(PCPDynamicScreen* ds) {
   DynamicScreen_done(&ds->super);
   Object_delete(ds->table);
   free(ds->columns);
}

static void PCPDynamicScreens_free(ATTR_UNUSED ht_key_t key, void* value, ATTR_UNUSED void* data) {
   PCPDynamicScreen* ds = (PCPDynamicScreen*) value;
   PCPDynamicScreen_done(ds);
}

void PCPDynamicScreens_done(Hashtable* table) {
   Hashtable_foreach(table, PCPDynamicScreens_free, NULL);
}

void PCPDynamicScreen_appendTables(PCPDynamicScreens* screens, Machine* host) {
   PCPDynamicScreen* ds;

   for (size_t i = 0; i < screens->count; i++) {
      if ((ds = (PCPDynamicScreen*)Hashtable_get(screens->table, i)) == NULL)
         continue;
      ds->table = InDomTable_new(host, ds->indom, ds->key);
   }
}

void PCPDynamicScreen_appendScreens(PCPDynamicScreens* screens, Settings* settings) {
   PCPDynamicScreen* ds;

   for (size_t i = 0; i < screens->count; i++) {
      if ((ds = (PCPDynamicScreen*)Hashtable_get(screens->table, i)) == NULL)
         continue;
      if (ds->defaultEnabled == false)
         continue;
      const char* tab = ds->super.heading;
      Settings_newDynamicScreen(settings, tab, &ds->super, &ds->table->super);
   }
}

/* called when htoprc .dynamic line is parsed for a dynamic screen */
void PCPDynamicScreen_addDynamicScreen(PCPDynamicScreens* screens, ScreenSettings* ss) {
   PCPDynamicScreen* ds;

   for (size_t i = 0; i < screens->count; i++) {
      if ((ds = (PCPDynamicScreen*)Hashtable_get(screens->table, i)) == NULL)
         continue;
      if (String_eq(ss->dynamic, ds->super.name) == false)
         continue;
      ss->table = &ds->table->super;
   }
}

void PCPDynamicScreens_addAvailableColumns(Panel* availableColumns, Hashtable* screens, const char* screen) {
   Vector_prune(availableColumns->items);

   bool success;
   unsigned int key;
   success = DynamicScreen_search(screens, screen, &key);
   if (!success)
      return;

   PCPDynamicScreen* dynamicScreen = Hashtable_get(screens, key);
   if (!dynamicScreen)
      return;

   for (unsigned int j = 0; j < dynamicScreen->totalColumns; j++) {
      PCPDynamicColumn* column = dynamicScreen->columns[j];
      const char* title = column->super.heading ? column->super.heading : column->super.name;
      const char* text = column->super.description ? column->super.description : column->super.caption;
      char description[256];
      if (text)
         xSnprintf(description, sizeof(description), "%s - %s", title, text);
      else
         xSnprintf(description, sizeof(description), "%s", title);
      Panel_add(availableColumns, (Object*) ListItem_new(description, j));
   }
}
