#define _GNU_SOURCE
#include <locale.h>
#include "postgres.h"
#include "funcapi.h"

#include "taggedtypesuser.h"

// Turns a text into a char*
static inline char *text_to_charp( text * t )
{
  char *s = (char*) palloc( VARSIZE( t ) );
  
  memcpy( s, VARDATA( t ), VARSIZE( t ) - VARHDRSZ );
  s[ VARSIZE( t ) - VARHDRSZ ] = 0;
  
  return s;
}


PG_FUNCTION_INFO_V1(locale_tt_text_comp);

Datum
locale_tt_text_comp(PG_FUNCTION_ARGS)
{
  struct TaggedTypeInfo *tti = GetTaggedTypeDetails( procLookupArgType( fcinfo->flinfo->fn_oid, 0 ) );
  
  Datum arg1 = PG_GETARG_DATUM(0);
  Datum arg2 = PG_GETARG_DATUM(1);
  
  text *text1 = DatumGetTextP( ExtractTaggedTypeDatum( tti, arg1 ) );
  text *text2 = DatumGetTextP( ExtractTaggedTypeDatum( tti, arg2 ) );

  text *tag;
  int32	res;
  locale_t	locale;
  
  if( ExtractTaggedTypeOid( tti, arg1 ) != ExtractTaggedTypeOid( tti, arg2 ) )
  {
    ereport( ERROR, (errmsg("Different collations specified")));
  }
  
  tag = FindTagByOid( tti, ExtractTaggedTypeOid( tti, arg1 ) ); 
  locale = newlocale( LC_COLLATE_MASK, text_to_charp( tag ), NULL );
  if( !locale )
  {
    ereport( ERROR, (errmsg("Locale '%s' not supported by library", text_to_charp( tag ) ) ) );
  }
  res = strcoll_l( text_to_charp( text1 ), text_to_charp( text2 ), locale );
  
  return Int32GetDatum( res );
}

PG_FUNCTION_INFO_V1(locale_text_comp);

Datum
locale_text_comp(PG_FUNCTION_ARGS)
{
  text *text1 = PG_GETARG_TEXT_P(0);
  text *text2 = PG_GETARG_TEXT_P(1);
  
  text *locale_text = PG_GETARG_TEXT_P(2);
  int32	res;
  locale_t	locale;
  
  locale = newlocale( LC_COLLATE_MASK, text_to_charp( locale_text ), NULL );

  if( !locale )
  {
    ereport( ERROR, (errmsg("Locale '%s' not supported by library", text_to_charp( locale_text ) ) ) );
  }
  res = strcoll_l( text_to_charp( text1 ), text_to_charp( text2 ), locale );
  
  return Int32GetDatum( res );
}

