/***************************************************************************
 *   copyright           : (C) 2004 by Hendrik Sattler                     *
 *   mail                : post@hendrik-sattler.de                         *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "pbookfile.h"
#include "helper.h"
#include "scmxx.h"

#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

/* fill the pbook_phone_entry from a text line
 */
int pbook_file_str2entry (char* line,
			  struct pbook_entry* entry)
{
  //pointers in line
  char* slot;
  char* number;
  char* text;
  char* temp;

  if (str_len(line) == 0 || entry == NULL) return -1;

  /* Policy is to not trust in what the phone delivers
   * Thus, full checking must be done.
   * Format: slot,"number",numtype,"text"
   */
  slot = line;
  while(isdigit((int)*line) && *line != 0) ++line;
  if (*line != ',' || *line == 0) return 0;
  ++line;
  if (*line != '"' || *line == 0) return 0;
  number = ++line;
  while (*line != '"' && *line != 0) ++line;
  if (*line != '"' || *line == 0) return 0;
  ++line;
  if (*line != ',' || *line == 0) return 0;
  ++line;
  if (*line != '"' || *line == 0) return 0;
  text = ++line;
  if ((line=strrchr(text-1,'"')) <= text-1) return 0;
  ++line;
  if (strcmp(line,"\n") != 0 && //Unix
      strcmp(line,"\r\n") != 0 && //Windows
      strcmp(line,"\r") != 0) { //Mac
    return 0;
  }

  entry->slot = atoi(slot);
  entry->number = strn_dup(number,strchr(number,'"')-number);
  temp = strn_dup(text,strchr(text,'"')-text);
  entry->text = convert_from_system(temp);
  mem_realloc(temp,0);
  return 1;
}

int pbook_file_read_line (FILE* fp,struct pbook_entry* entry) {
  char buffer[BUFSIZ];
  
  if (fp == NULL || entry == NULL) return -1;

  memset(buffer,0,1);
  if (fgets(buffer,BUFSIZ,fp) == NULL) return -1;
  else return pbook_file_str2entry(buffer,entry);
}

struct pbook_entry** pbook_file_read (char* file) {
  FILE* fp;
  size_t i = 0;
  struct pbook_entry** plist;
  size_t psize = 100;
  int status;
  
  if (file == NULL) return NULL;

  if (str_len(file) && strcmp(file,"-") != 0) {
    fp = fdopen(file_open_input(file),"r");
    if (fp == NULL) return NULL;
  } else {
    fp = stdin;
  }

  plist = mem_alloc(psize*sizeof(*plist),0);
  do {
    if (i+1 >= psize) {
      psize += 100;
      plist = mem_realloc(plist,psize*sizeof(*plist));
    }
    plist[i] = mem_alloc(sizeof(**plist),0);
    status = pbook_file_read_line(fp,plist[i]);
    switch (status) {
    case 1: //successful read of entry
      ++i;
      break;
    case -1: //end of file
      plist[i] = mem_realloc(plist[i],0);
      plist[i] = NULL;
      break;
    case 0: //failure in entry or file
      plist[i] = mem_realloc(plist[i],0);
      plist[i] = NULL;
      i=0;
      while (plist[i] != NULL) {
	mem_realloc(plist[i]->number,0);
	mem_realloc(plist[i]->text,0);
	mem_realloc(plist[i],0);
	++i;
      }
      mem_realloc(plist,0);
      return NULL;
    }
  } while (status == 1);
  plist = mem_realloc(plist,(i+1)*sizeof(*plist));
  if (fp != stdin) {
    fclose(fp);
  }
  return plist;
}

int pbook_file_write_entry (FILE* fp, struct pbook_entry* entry)
{
  char* number = entry->number;
  char* text;
  int status;

  if (number == NULL) number = "";
  text = convert_to_system(entry->text,REPMODE_ESCAPE_CHARS);
  if (text == NULL) {
    if (entry->text != NULL) return 0;
    else text = str_dup("");
  }
  status = fprintf(fp,"%u,\"%s\",\"%s\"\n",entry->slot,number,text);
  mem_realloc(text,0);
  if (status == 0) return 0;
  else return 1;
}

int pbook_file_write (char* file, struct pbook_entry** entries)
{
  unsigned int i = 0;
  FILE* fp;

  if (file == NULL) return 0;

  if (str_len(file) && strcmp(file,"-") != 0) {
    fp = fdopen(file_open_output(file),"w");
    if (fp == NULL) return 0;
  } else {
    fp = stdout;
  }

  for (; entries[i] != NULL; ++i) {
    if (pbook_file_write_entry(fp,entries[i]) == 0) return 0;
  }
  return 1;
}
