
/**
 *
 *  This file is part of the kdewebdev package
 *  Copyright (c) 2001 Keith Isdale <keith@kdewebdev.org>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License as
 *  published by the Free Software Foundation; either version 2 of
 *  the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 **/

#include "kxsldbgpart/libxsldbg/xsldbg.h"

#include <libxslt/xsltutils.h>
#include <version.h>

#ifdef HAVE_READLINE
#include <readline/readline.h>
#ifdef HAVE_HISTORY
#include <readline/history.h>
#endif
#endif

#include <string.h>
#include "kxsldbgpart/libxsldbg/xsldbgmsg.h"
#include "kxsldbgpart/libxsldbg/xsldbgio.h"
#include "kxsldbgpart/libxsldbg/options.h"

#include <kapplication.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kglobal.h>
#include <kdebug.h>
/* Forward delare private functions */
static int notifyXsldbgAppSimple(XsldbgMessageEnum type, const void *data);
static int notifyStateXsldbgAppSimple(XsldbgMessageEnum type, int commandId,
			   XsldbgCommandStateEnum commandState, const char *text);
static int notifyTextXsldbgAppSimple(XsldbgMessageEnum type, const char *text);
static xmlChar * xslDbgShellReadlineSimple(xmlChar * prompt);


static const char *description = I18N_NOOP("A KDE console application for xsldbg, an XSLT debugger");

static const char *version = KXSLDBG_VERSION;

class XsldbgApp : public KApplication
{
 public:
    XsldbgApp()
	:KApplication(false)
    {
	xsldbgSetAppFunc(notifyXsldbgAppSimple);
	xsldbgSetAppStateFunc(notifyStateXsldbgAppSimple);
	xsldbgSetTextFunc(notifyTextXsldbgAppSimple);
	xsldbgSetReadlineFunc(xslDbgShellReadlineSimple);
    }

    int exec(){
	return xsldbgMain(0, 0);
    }

};

int main(int argc, char **argv)
{
    KLocale::setMainCatalog("kxsldbg"); // Translations come from KXSLDbg's catalog

    QString xsldbgRunTimeInfo(i18n("Using libxml %1, libxslt %2 and libexslt %3\n", xmlParserVersion, xsltEngineVersion, exsltLibraryVersion));
    QString libxmlCompileTimeInfo(i18n("xsldbg was compiled against libxml %1, libxslt %2 and libexslt %3\n", LIBXML_VERSION, LIBXSLT_VERSION, LIBEXSLT_VERSION));
    QString libxsltCompileTimeInfo(i18n("libxslt %1 was compiled against libxml %2\n", xsltLibxsltVersion, xsltLibxmlVersion));
    QString libexsltCompileTimeInfo(i18n("libexslt %1 was compiled against libxml %2\n", exsltLibexsltVersion, exsltLibxmlVersion));
    QString freeFormText = xsldbgRunTimeInfo + libxmlCompileTimeInfo + libxsltCompileTimeInfo + libexsltCompileTimeInfo;

    KAboutData about("xsldbg", 0, ki18n("Xsldbg"), version, ki18n(description), KAboutData::License_GPL, ki18n("(C) 2003 Keith Isdale"), ki18n(freeFormText.toUtf8().constData()), 0, "keith@kdewebdev.org");
    about.addAuthor( ki18n("Keith Isdale"), KLocalizedString(), "keith@kdewebdev.org" );
    KCmdLineArgs::init(argc, argv, &about);

    KCmdLineOptions options;
    options.add("shell", ki18n("Start a shell"));
    options.add("cd <path>", ki18n("Path to change into before loading files"));
    options.add("param <name>:<value>", ki18n("Add a parameter named <name> and value <value> to XSL environment"));
    options.add("lang <LANG>", ki18n("Use ISO 639 language code specified; for example en_US"));
    options.add("output file", ki18n("Save to a given file. See output command documentation"));
    options.add("version", ki18n("Show the version of libxml and libxslt used"));
    options.add("verbose", ki18n("Show logs of what is happening"));
    options.add("timing", ki18n("Display the time used"));
    options.add("repeat", ki18n("Run the transformation 20 times"));
    options.add("noautoloadconfig", ki18n("Automatically load/save configuration."));
    #ifdef LIBXML_DEBUG_ENABLED
    options.add("debug", ki18n("Dump the tree of the result instead"));
    #endif
    options.add("novalid", ki18n("Disable the DTD loading phase"));
    options.add("noout", ki18n("Disable the output of the result"));
    options.add("maxdepth val", ki18n("Increase the maximum depth"));
    #ifdef LIBXML_HTML_ENABLED
    options.add("html", ki18n("The input document is(are) an HTML file(s)"));
    #endif
#ifdef LIBXML_DOCB_ENABLED
    options.add("docbook", ki18n("The input document is SGML docbook"));
    #endif
    options.add("nonet", ki18n("Disable the fetching DTDs or entities over network"));
    #ifdef LIBXML_CATALOG_ENABLED
    options.add("catalogs", ki18n("Use the catalogs from $SGML_CATALOG_FILES"));
    #endif
#ifdef LIBXML_XINCLUDE_ENABLED
    options.add("noxinclude", ki18n("Disable XInclude processing on document input"));
    #endif
    options.add("profile", ki18n("Print profiling information"));
    options.add("nogdb", ki18n("Do not run gdb compatability mode and print less information"));
    options.add("autoencode", ki18n("Detect and use encodings in the stylesheet"));
    options.add("utf8input", ki18n("Treat command line input as encoded in UTF-8"));
    options.add("preferhtml", ki18n("Use HTML output when generating search reports"));
    options.add("stdout", ki18n("Print all error messages to stdout, normally error messages go to stderr"));
    options.add("noautorestart", ki18n("Disable the automatic restarting of execution when current processing pass is complete"));
    options.add("+XSLSource", ki18n("XSL script to run"));
    options.add("+XMLData", ki18n("XML data to be transformed"));
    KCmdLineArgs::addCmdLineOptions( options );
    XsldbgApp app;

    return app.exec();;
}

/* Private implementation of messaging functions */
int notifyXsldbgAppSimple(XsldbgMessageEnum type, const void *data)
{
  Q_UNUSED(type);
  Q_UNUSED(data);
  return 1;
}

int notifyStateXsldbgAppSimple(XsldbgMessageEnum type, int commandId,
			   XsldbgCommandStateEnum commandState, const char *text)
{
  Q_UNUSED(type);
  Q_UNUSED(commandId);
  Q_UNUSED(commandState);
  Q_UNUSED(text);
  return 1;
}

int notifyTextXsldbgAppSimple(XsldbgMessageEnum type, const char *text)
{
  Q_UNUSED(type);
  Q_UNUSED(text);
  return 1;
}


/* use this function instead of the one that was in debugXSL.c */
/**
 * xslShellReadline:
 * @prompt:  the prompt value
 *
 * Read a string
 *
 * Returns a copy of the text inputed or NULL if EOF in stdin found.
 *    The caller is expected to free the returned string.
 */
xmlChar *
xslDbgShellReadlineSimple(xmlChar * prompt)
{

  static char last_read[DEBUG_BUFFER_SIZE] = { '\0' };

#ifdef HAVE_READLINE

      xmlChar *line_read;

      if (optionsGetIntOption(OPTIONS_STDOUT) == 0){
	/* Get a line from the user. */
	line_read = (xmlChar *) readline((char *) prompt);

	/* If the line has any text in it, save it on the history. */
	if (line_read && *line_read) {
	  char *temp = (char*)line_read;
	  add_history((char *) line_read);
	  strncpy((char*)last_read, (char*)line_read, DEBUG_BUFFER_SIZE - 1);
	  /* we must ensure that the data is free properly */
	  line_read = xmlStrdup((xmlChar*)line_read);
	  free(temp);
	} else {
	  free(line_read);
	  /* if only <Enter>is pressed then try last saved command line */
	  line_read = xmlStrdup((xmlChar*)last_read);
	}
      }else{
	/* readline library will/may  echo its output which is not wanted
	   when running in gdb mode.*/
	char line_buffer[DEBUG_BUFFER_SIZE];

	if (prompt != NULL)
	  xsltGenericError(xsltGenericErrorContext, "%s", prompt);
	if (!fgets(line_buffer, sizeof(line_buffer) - 1, stdin)){
	  line_read = NULL;
	}else{
	  line_buffer[DEBUG_BUFFER_SIZE - 1] = 0;
	  if ((strlen(line_buffer) == 0) || (line_buffer[0] == '\n')){
	    line_read = xmlStrdup((xmlChar*)last_read);
	  }else{
	    add_history((char *) line_buffer);
	    line_read = xmlStrdup((xmlChar*)line_buffer);
	    strncpy((char*)last_read, (char*)line_read, sizeof(last_read) - 1);	  	  }
	}

      }
      return (line_read);

#else
      char line_read[DEBUG_BUFFER_SIZE];

      if (prompt != NULL)
        xsltGenericError(xsltGenericErrorContext, "%s", prompt);
	  fflush(stderr);
      if (!fgets(line_read, DEBUG_BUFFER_SIZE - 1, stdin))
        return (NULL);
      line_read[DEBUG_BUFFER_SIZE - 1] = 0;
      /* if only <Enter>is pressed then try last saved command line */
      if ((strlen(line_read) == 0) || (line_read[0] == '\n')) {
	  strncpy(line_read, last_read, sizeof(line_read) - 1);
      } else {
	  strcpy(last_read, line_read);
      }
      return xmlStrdup((xmlChar*)line_read);
#endif

    }
/*
void xsldbgThreadCleanup(void);
*/
/* thread has died so cleanup after it not called directly but via
 notifyXsldbgApp*/
/*
void
xsldbgThreadCleanup(void)
{

}
*/


