#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <support.h>
#include "kerbind.h"
#include "gs_descr.h"


extern char cfg_filename[160];	/* Used to build debug log filename */
static char DEBUG_LOGFILE[160];
static char DEBUG_LOG_OLD[160];

static char *prologs[] = {
  "",		/* DBG_NOMSG */
  "): FATAL: ",	/* DBG_FATAL */
  "): ERROR: ",	/* DBG_ERROR */
  "): ",	/* DBG_SYSCALL */
  "): TRACE: ",	/* DBG_TRACE */
};

typedef char *charp;
typedef void *voidp;

int debug_level = 0;


static char *get_procname(int pid)
{
  char buf[FILENAME_MAX + 5];
  static char oops[] = "<<name unknown>>";
  long h = 0, i;
  char *s;

  h = d_opendir("U:\\PROC", 0);
  if (h < 0 && (h & 0xFF000000UL) != 0xFF000000UL)
    return oops;

  while ((i = d_readdir((short)sizeof(buf), h, buf)) == 0) {
    s = strchr(buf + 4, '.');
    if (!s || atoi(s+1) != pid)
      continue;
    *s = '\0';	/* found our process */
    break;
  }
  d_closedir(h);

  return (i == 0 ? buf+4 : oops);
}


int init_debug()
{
  register char *s = gs_getvstr("GLUESTIK_TRACE");
  long l;

  debug_level = atoi(s);
  if (debug_level < DBG_NOMSG || debug_level > DBG_TRACE) {
    c_conws("Debug level out of range; defaulting to zero\r\n");
    debug_level = 0;
  }

  /* Put the trace log in the same directory as the config file. */
  strcpy(DEBUG_LOGFILE, cfg_filename);
  s = strrchr(DEBUG_LOGFILE, '\\');
  if (!s) {
    c_conws("No path specified for config file\r\n");
    return 0;
  }
  s[1] = '\0';
  strcpy(DEBUG_LOG_OLD, DEBUG_LOGFILE);
  strcat(DEBUG_LOGFILE, "GLUESTIK.LOG");
  strcat(DEBUG_LOG_OLD, "GLUESTIK.OLD");

  f_delete(DEBUG_LOG_OLD);
  f_rename(0, DEBUG_LOGFILE, DEBUG_LOG_OLD);
  l = f_create(DEBUG_LOGFILE, 0);
  if (l < 0) {
    c_conws("Unable to create trace log ");
    c_conws(DEBUG_LOGFILE);
    c_conws("\r\n");
    return 0;
  }
  f_close((int)(short)l);

  return 1;
}


void log_entry_raw(int pid, int lev, const char *line)
{
  char header[64];
  long l;
  int fd;

  strcpy(header, "pid ");
  _itoa(pid, header+4, 10);
  strcat(header, " (");
  strcat(header, get_procname(pid));
  strcat(header, prologs[lev]);

  l = f_open(DEBUG_LOGFILE, 2);
  if (l < 0) {
    c_conws("Unable to open debug log ");
    c_conws(DEBUG_LOGFILE);
    c_conws("\r\n");
  } else {
    fd = (int)(short)l;
    f_seek(0L, fd, SEEK_END);
    f_write(fd, strlen(header), header);
    f_write(fd, strlen(line), line);
    f_close(fd);
  }
}

void log_entry(int lev, const char *fmt, ...)
{
  va_list ap;
  char line[512];

  if (lev > debug_level)
    return;

  va_start(ap, fmt);
  log_entry_fmt(line, fmt, ap);
  va_end(ap);

  log_entry_raw(p_getpid(), lev, line);
}

void cleanup_debug()
{
}
