/*
 * No rights reserved.  This code is public domain.
 *
 * - Rob Mayoff <mayoff@dqd.com>
 */

static char rcsid[] = "@(#) $Id: utils.c,v 1.6 2004/10/16 02:56:31 mayoff stable $";

#include "ns.h"
#include "utils.h"

static Tcl_CmdProc internalRedirectCmd;
static Tcl_CmdProc registerProxyCmd;
static Tcl_CmdProc findMaxMatchingCharsCmd;
static Ns_OpProc proxyOp;
static Ns_Callback deleteProxyOp;

static int
internalRedirectCmd(ClientData clientData, Tcl_Interp *interp,
    int argc, char **argv)
{
    Ns_Conn *conn;

    if (argc != 2) {
	Tcl_AppendResult(interp, "wrong # of args: should be \"",
	    argv[0], " new-url\"", NULL);
	return TCL_ERROR;
    }

    Ns_Log(Debug, "InternalRedirectCmd(%s)", argv[1]);

    conn = Ns_TclGetConn(interp);
    if (conn == NULL) {
	Tcl_AppendResult(interp, "no connection", NULL);
	return TCL_ERROR;
    }

    return Ns_ConnRedirect(conn, argv[1]);
}

static int
proxyOp(void *arg, Ns_Conn *conn)
{
    char *script;
    Tcl_Interp *interp;
    Ns_DString ds;

    script = (char *) arg;
    Ns_DStringInit(&ds);

    if (Ns_TclEval(&ds, NULL, script) != NS_OK) {
	Ns_ConnReturnInternalError(conn);
    }

    return NS_OK;
}

static void
deleteProxyOp(void *arg)
{
    ns_free(arg);
}

static int
registerProxyCmd(ClientData clientData, Tcl_Interp *interp,
    int argc, char **argv)
{
    Ns_Conn *conn;
    char *cmd, *method, *protocol, *script;

    cmd = argv[0];
    if (argc != 4) {
	Tcl_AppendResult(interp, "wrong # of args: should be \"",
	    cmd, " method protocol script\"", NULL);
	return TCL_ERROR;
    }

    method = argv[1];
    protocol = argv[2];
    script = ns_strdup(argv[3]);

    Ns_RegisterProxyRequest(NULL, method, protocol, proxyOp, NULL,
	script);
    return TCL_OK;
}

static int
findMaxMatchingCharsCmd(ClientData clientData,
    Tcl_Interp *interp, int argc, char **argv)
{
    char *cmd, *s1, *s2;
    char *p, *q, *r;
    int m = 0, best = 0;

    cmd = argv[0];
    if (argc != 3) {
	Tcl_AppendResult(interp, "wrong # of args: should be \"",
	    cmd, " string1 string2\"", NULL);
	return TCL_ERROR;
    }

    s1 = argv[1];
    s2 = argv[2];

    best = 0;

    if (*s1 && *s2) {
	r = s1 + 1;
	while (*r) r++;

	while (r > s1) {
	    --r;

	    m = 0;
	    for (p = r, q = s2; *p && *q; p++, q++) {
		if (*p == *q)
		    m++;
	    }
	    if (m > best) best = m;
	}

	r = s2 + 1;
	while (*r) {
	    m = 0;
	    for (p = s1, q = r; *p && *q; p++, q++) {
		if (*p == *q)
		    m++;
	    }
	    if (m > best) best = m;

	    r++;
	}
    }

    sprintf(interp->result, "%d", best);
    return TCL_OK;
}

void
addNonversionedCommands(Tcl_Interp *interp)
{
    Tcl_CreateCommand(interp, "dqd_md5", MD5Cmd, NULL, NULL);
    Tcl_CreateCommand(interp, "dqd_internalredirect",
	internalRedirectCmd, NULL, NULL);
    Tcl_CreateCommand(interp, "dqd_register_proxy",
	registerProxyCmd, NULL, NULL);
    Tcl_CreateCommand(interp, "dqd_find_max_matching_chars",
	findMaxMatchingCharsCmd, NULL, NULL);
}

