#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>

#include <stdio.h> /* nur für printf nötig */

#include <malloc.h> /* wegen alloca; nicht C-Standard! */

/*** mysql Zeugs, ohne das es hier nicht geht; muss natürlich wieder raus ***/
#define UDF_INIT void
typedef long longlong;

typedef struct {
int arg_count;
void **args;
int *lengths;
} UDF_ARGS;
/************************************************/


longlong levenshtein_k_base(UDF_INIT *initid, char *str1, char *str2, int distance, char *is_null, char *error)
{
  return 1; /* hier deine Implementierung; ich ging davon aus, dass hier für "beste" Übereinstimmung 0 geliefert wird, sonst >0 */
}

longlong abweichung(UDF_INIT *initid,char *suche,char *in,const char *e,int distance,char *is_null,char *error)
{
#define MINDESTLAENGE 4
  longlong r=LONG_MAX;  /* "schlechteste" Übereinstimmung annehmen */
  while( in!=e )  /* im zu durchsuchenden char-Array alle "Worte" durchsuchen, also z.B. "abcd" in "xyz\0qwer\0usw\0" */
  {
    assert( (printf("%s ? %s\n",suche,in),1) );
    if( strlen(suche)>=MINDESTLAENGE && strlen(in)>=MINDESTLAENGE )   /* nur ab MINDESTLAENGE Zeichen die Suche durchführen */
    {
      if( !strcoll(in,suche) ) return 0; /* falls identisch (inkl. locale), dann "beste" Übereinstimmung liefern + Ende */
      if(  strstr(in,suche) ) return 0;  /* falls enthalten, dann "beste" Übereinstimmung liefern + Ende */
      {
        longlong tmp=levenshtein_k_base(initid,suche,in,distance,is_null,error);
        assert( tmp>=0 );  /* Code geht davon aus, dass keine neg. Werte geliefert werden */
        if( 0==tmp )
          return 0; /* falls <lv> "beste" Übereinstimmung liefert => Ende */
        if( tmp<r ) r=tmp; /* sonst den besten Wert merken */
      }
    }
    in+=strlen(in)+1;
  }
  return r;
}

longlong relevance(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
  longlong r=LONG_MAX;  /* "schlechteste" Übereinstimmung annehmen */

  /* Such-Array bilden z.B. "C Entwickler" => "c\0entwickler\0centwickler\0" */
  char *s0=alloca(2+2*(args->lengths[0])),*c=s0?s0:(abort(),NULL),*e=c;  memcpy(c,args->args[0],args->lengths[0]);c[args->lengths[0]]=0;
  while(*e) *e=tolower((unsigned char)*e),e++;
  strcpy(++e,s0);  s0[strlen(s0)]=' ';
  while(*e) {if(*e==' ') memmove(e,e+1,strlen(e)); ++e;} ++e;
  c=s0;
  while(*c) {if(*c==' ') *c=0; ++c;}
  /***************************************************************************/

  /* Inserattitel-Wörter durchsuchen und Ende, falls "beste" Übereinstimmung hier schon gefunden */
  c=s0;
  {
    char *s1=alloca(1+args->lengths[1]),*x=s1?s1:(abort(),NULL); memcpy(x,args->args[1],args->lengths[1]);x[args->lengths[1]]=0;
    while(*x) *x=tolower((unsigned char)*x),x++;
    x=s1;
    while(*x) {if(*x==' ') *x=0; ++x;} ++x;
    while( c!=e ) /* alle Such-Wörter durchlaufen */
    {
      longlong tmp=abweichung(initid,c,s1,x,*(int *) args->args[3],is_null,error);
      if( 0==tmp )
        return 0;
      if( tmp<r ) r=tmp;
      c+=strlen(c)+1;
    }
  }

  /* Inserattext-Wörter durchsuchen und Ende, falls "beste" Übereinstimmung hier gefunden */
  c=s0;
  {
    char *s1=alloca(1+args->lengths[2]),*x=s1?s1:(abort(),NULL); memcpy(x,args->args[2],args->lengths[2]);x[args->lengths[2]]=0;
    while(*x) *x=tolower((unsigned char)*x),x++;
    x=s1;
    while(*x) {if(*x==' '||*x=='|') *x=0; ++x;} ++x;
    while( c!=e )
    {
      longlong tmp=abweichung(initid,c,s1,x,*(int *) args->args[3],is_null,error);
      if( 0==tmp )
        return 0;
      if( tmp<r ) r=tmp;
      c+=strlen(c)+1;
    }
  }

  return r; /* "besten" d.h. minimalen Wert vom lev.algo. rückliefern */
}

int main()
{
  int i=1;
  void *s[]={"C Entwickler","Software Developer","Software Entwickler|C Entwickler|Programmierer",&i};
  int l[]={12,18,46,0};
  UDF_ARGS u={4,s,l};
  printf("%ld",relevance(0,&u,0,0));
  return 0;
}

