/************************************************************
**
** Application: TaskLib
**
** Title:       c.xdeb
**
*************************************************************/

/*
*
* Copyright (c) 2015, Chris Johnson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the copyright holder nor the names of their
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/


/*->c.deb */

#include "debugDefs.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>
#include <stdarg.h>


#include "h.os"
#include "h.bbc"
#include "h.akbd"
#include "h.wimpt"
#include "h.wimp"
#include "h.swis"
#include "h.constants"
#include "h.fsx"
#include "h.bits"
#include "h.etc"
#include "h.wos"
#include "h.poll"
#include "h.timex"
#include "h.os2"

#include "h.deb"


#define isshift akbd_pollsh()
#define isctrl  akbd_pollctl()

//static char db_log_fname[256];
//static int  db_log_on = 0;

static FILE * dbfp;



//#ifndef DEMO

//#ifndef PROD


#define DAPPEND

void dprintf (int line, char *format, ...)
{
  va_list     args;
  char        v[512];
  char        string[512];
  os_regset   rx;

  va_start (args, format);
  vsprintf (v, format, args);

  sprintf (string, "%s$Debug", wimpt_programname ());
  if (getenv (string) != NULL)
  {
    rx.r[0] = 202;
    rx.r[1] = 0;
    rx.r[2] = -1;

    os_swix (OS_Byte, &rx);

    if (!(rx.r[1] & 0x10))
    {
#ifdef DAPPEND
      if (!dbfp)
	dbfp = fopen ("xx", "ab+");
      if (dbfp)
      {
	fprintf (dbfp, "%s\n", v);
	fclose (dbfp);
	dbfp = NULL;
      }
#else
      if (!dbfp)
	dbfp = fopen ("xx", "wb");
      if (dbfp)
	fprintf (dbfp, "%s\n", v);
#endif
// end DAPPEND
    }
    else
    {
      bbc_vdu (4);
      bbc_vdu (30);
      while (line--)
	bbc_vdu (10);
      printf ("%-40s", v);
      bbc_vdu (5);
      if (isctrl)
	bbc_get ();
    }
  }

  va_end (args);
}

/* Following code is no longer used */
#ifdef NEVER
//#else

void dprintf (int line, char *format, ...)
{
  va_list     args;
  char        v[128];

  va_start (args, format);
  vsprintf (v, format, args);

  va_end (args);

  USE (line);
}

//#endif
// end of PROD

//#else

void dprintf (int line, char *format, ...)
{
  va_list     args;
  char        v[128];

  va_start (args, format);
  vsprintf (v, format, args);

  va_end (args);
}

#endif
// end of demo


/* in dbug mode, we use this signal handler, which gives a trace back */

typedef void SignalHandler (int);

static debfn debugfn;


//#ifndef PROD

static void debug_handler (int sig)
{
  if (sig != SIGINT || isshift)
  {
    if (debugfn)
      debugfn ();
    os_cli ("*spool zz");
    raise (SIGTERM);		/* get a precious stack backtrace! */
    os_cli ("*spool");
    exit (0);
  }
  else
  {
    signal (SIGINT, &debug_handler);
  }
}




static void debugenter (int userhandle)
{
  fx (229, 0, 0);
  USE (userhandle);
}


static void debugexit (int userhandle)
{
  fx (229, 1, 0);
  /* the following instruction inhibits some function keys including
   * control+shift+F12 so has been removed
  fx (224, 0, 0); */
  USE (userhandle);
}


//#endif


void debugenable (debfn xdeb)
{
//#ifndef PROD

  char        string[128];

  debugfn = xdeb;

  sprintf (string, "%s$Debug", wimpt_programname ());
  if (getenv (string))
  {
    signal (SIGSEGV, &debug_handler);
    signal (SIGINT, &debug_handler);
    signal (SIGFPE, &debug_handler);
    signal (SIGILL, &debug_handler);
    signal (SIGSTAK, &debug_handler);

    signal (SIGTERM, SIG_DFL);

    addpollenter (debugenter, 0);
    addpollexit (debugexit, 0);
  }

//#else

//  USE (xdeb);

//#endif
}


int debugactive (void)
{
//#ifndef PROD

  char        string[128];

  sprintf (string, "%s$Debug", wimpt_programname ());
  return (getenv (string) != NULL);

//#else

//  return (0);

//#endif
}


int debugactive2 (void)
{
//#ifndef PROD

  char        string[128];

  sprintf (string, "%s$Debug2", wimpt_programname ());
  return (getenv (string) != NULL);

//#else

//  return (0);

//#endif
}




/**************************************************************************/

/**************************************************************************/

/**************************************************************************/

/* All the following code functionality has been transferred to the
 * source file c.log */

/**************************************************************************/




#ifdef NEVER



void lstart (void)
{
#ifdef LOGGING_ON

  time_t current ;
  struct tm *converted_time ;
  size_t length ;
  char   t[128] ;

  /* Get the time and convert to suitable format */
  current = time (NULL) ;
  converted_time = localtime (&current) ;
  length = strftime (t, sizeof(t), "started at %H:%M:%S on %d %b %Y",
                                        converted_time) ;

  /* and enter in the log, with leading blank line and stars */
  lprintf ("\n************************\n%s %s", wimpt_programname (), t);

#endif

  return;
}



/**************************************************************************/



void db_log_printf (char *format, ...)
{
  va_list     args;
  char        v[512];
  char        string[512];
  char       *p;
  FILE       *fp;

  if (db_log_on)
  {
    va_start (args, format);
    vsprintf (v, format, args);

    fp = fopen (db_log_fname, "ab+");
    if (fp)
    {
      fprintf (fp, "%s\n", v);
      fclose (fp);
    }
    va_end (args);
  }
}





void db_log_error (char *v, os_error * err)

{
  FILE       *fp;
//  char        string[256];
  char       *p;

  if (db_log_on && err)
  {
    fp = fopen (db_log_fname, "ab+");
    if (fp)
    {
      fprintf (fp, "%s (%s)\n", v, err->errmess);
      fclose (fp);
    }
  }
}




void db_log_set_enable (BOOL state)

{
  FILE       *fp;

  fp = fopen (db_log_fname, "ab+");
  if (fp)
  {
    if (state)
      fprintf (fp, "DB logging enabled\n");
    else
      fprintf (fp, "DB logging disabled\n");
    fclose (fp);
  }
  db_log_on = state;
}



void db_log_init (BOOL debug, BOOL clear, char * app_name)

{
  FILE       *fp;
  char string[256];
  time_t current ;
  struct tm *converted_time ;
  size_t length ;


  db_log_on = debug;
  sprintf (db_log_fname, "<%s$Dir>.dblog", app_name);
  /* Do we start with an empty file */
  if (clear)
  {
    fp = fopen (db_log_fname, "wb");
  }
  else
  {
    fp = fopen (db_log_fname, "ab+");
  }
  /* now get the time and convert to suitable format */
  if (fp)
  {
    current = time (NULL) ;
    converted_time = localtime (&current) ;
    length = strftime (string, sizeof(string), "%H:%M:%S on %d %b %Y",
                                            converted_time) ;
    fprintf (fp, "// Debug log for %s initialised at %s\n//\n", app_name, string);
    if (debug)
      fprintf (fp, "DB logging enabled\n\n");
    else
      fprintf (fp, "DB logging disabled\n\n");
    fclose(fp);
    fs_settype (db_log_fname, TEXT);
  }

  return;
}



/**************************************************************************/




#endif
















