/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  backend-citationlistx.c defines the citationlistx output backend
  of refdbd
  markus@mhoenicka.de 2006-02-19
  $Id: backend-citationlistx.c,v 1.1.2.1 2006/02/22 20:50:14 mhoenicka Exp $

   This program 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 program 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 General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, see <http://www.gnu.org/licenses/>

  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

#include <string.h>
#include <syslog.h> /* for definitions of log message priorities */
#include <stdio.h>
#include <dbi/dbi.h>

#include "refdb.h"
#include "linklist.h"
#include "backend.h"
#include "backend-citationlistx.h"
#include "strfncs.h"
#include "refdbd.h"
#include "cgi.h"
#include "dbfncs.h"
#include "connect.h"

extern char refdblib[]; /* location of shareable files */

extern int n_log_level; /* numeric version of log_level */

/* forward declaration of local functions */
static char* print_citation(const char* item, struct renderinfo* ptr_rendinfo);


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  prepare_render_citationlistx(): writes a header for the citationlistx
                         output of a query

  int prepare_render_citationlistx returns 0 if successful, > 0 if failed

  struct renderinfo* ptr_rendinfo ptr to a structure with the info
                             how the reference should be rendered

 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int prepare_render_citationlistx(struct renderinfo* ptr_rendinfo) {
  char* new_ref;

  char* header;
  
  if ((header = assemble_header(ptr_rendinfo)) == NULL) {
    return 801;
  }

  new_ref = mstrcpy(*(ptr_rendinfo->ptr_ref), header, ptr_rendinfo->ptr_ref_len);
  free(header);

  if (new_ref == NULL) {
    LOG_PRINT(LOG_CRIT, get_status_msg(801));
    return 801;
  }
  else {
    *(ptr_rendinfo->ptr_ref) = new_ref;
  }

  new_ref = mstrcat(*(ptr_rendinfo->ptr_ref), "<CITATIONLIST>\n", ptr_rendinfo->ptr_ref_len, 0);

  if (new_ref == NULL) {
    LOG_PRINT(LOG_CRIT, get_status_msg(801));
    return 801;
  }

  *(ptr_rendinfo->ptr_ref) = new_ref;

  return 0;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  finish_render_citationlistx(): writes a footer for the citationlistx
                                 output of a query

  int finish_render_citationlistx returns 0 if successful, > 0 if failed

  struct renderinfo* ptr_rendinfo ptr to a structure with the info
                             how the reference should be rendered

 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int finish_render_citationlistx(struct renderinfo* ptr_rendinfo) {
  char* new_ref;

  new_ref = mstrcpy(*(ptr_rendinfo->ptr_ref), "\n</CITATIONLIST>\n", ptr_rendinfo->ptr_ref_len);

  if (new_ref == NULL) {
    LOG_PRINT(LOG_CRIT, get_status_msg(801));
    return 801;
  }

  *(ptr_rendinfo->ptr_ref) = new_ref;


  return 0;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  render_citationlistx() renders a RIS dataset for citationlistx export

  int render_citationlistx returns 0 if successful,> 0 if failed

  struct renderinfo* ptr_rendinfo ptr to a structure with the info
                             how the reference should be rendered

  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int render_citationlistx(struct renderinfo* ptr_rendinfo) {
  const char* item;
  char id[32] = "";
  dbi_conn conn;

  conn = dbi_result_get_conn(ptr_rendinfo->dbires);

  if (get_refdb_id(ptr_rendinfo->dbires, id) == NULL) {
    LOG_PRINT(LOG_WARNING, get_status_msg(234));
    return 234;
  }

  item = get_refdb_citekey(ptr_rendinfo->dbires);
  if (item && *item) {
    if (print_citation(item, ptr_rendinfo) == NULL) {
      return 801;
    }
  }

  return 0;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  print_citation(): writes citationlistx CITATION element

  char* print_citation returns a ptr to the modified string. Due to
                         reallocation this may be different from the
			 ptr passed to this function in the ptr_rendinfo
			 structure which is also updated accordingly

  const char* item ptr to the citation key to write

  struct renderinfo* ptr_rendinfo ptr to a structure with the info
                             how the reference should be rendered

 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static char* print_citation(const char* item, struct renderinfo* ptr_rendinfo) {
  char* new_ref;

  if (item != NULL) {
    if ((new_ref = mstrcat(*(ptr_rendinfo->ptr_ref), "<CITATION><XREF>ID", ptr_rendinfo->ptr_ref_len, 0)) == NULL) {
      LOG_PRINT(LOG_CRIT, get_status_msg(801));
      return NULL;
    }
    else {
      *(ptr_rendinfo->ptr_ref) = new_ref;
    }
    if ((new_ref = mstrcat(*(ptr_rendinfo->ptr_ref), (char*)item, ptr_rendinfo->ptr_ref_len, 0)) == NULL) { 
      LOG_PRINT(LOG_CRIT, get_status_msg(801));
      return NULL;
    }
    else {
      *(ptr_rendinfo->ptr_ref) = new_ref;
    }
    if ((new_ref = mstrcat(*(ptr_rendinfo->ptr_ref), "</XREF></CITATION>\n", ptr_rendinfo->ptr_ref_len, 0)) == NULL) {
      LOG_PRINT(LOG_CRIT, get_status_msg(801));
      return NULL;
    }
    else {
      *(ptr_rendinfo->ptr_ref) = new_ref;
    }
  }
  return *(ptr_rendinfo->ptr_ref);
}

