// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/**************************************************************************
*
*   Copyright (C) 2000-2016, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
***************************************************************************
*   file name:  pkgdata.c
*   encoding:   ANSI X3.4 (1968)
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2000may16
*   created by: Steven \u24C7 Loomis
*
*  common types for pkgdata
*/

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "unicode/utypes.h"
#include "unicode/putil.h"
#include "cmemory.h"
#include "cstring.h"
#include "pkgtypes.h"
#include "putilimp.h"

const char *pkg_writeCharListWrap(FileStream *s, CharList *l, const char *delim, const char *brk, int32_t quote)
{
    int32_t ln = 0;
    char buffer[1024];
    while(l != NULL)
    {
        if(l->str)
        {
            uprv_strncpy(buffer, l->str, 1020);
            buffer[1019]=0;

            if(quote < 0) { /* remove quotes */
                if(buffer[uprv_strlen(buffer)-1] == '"') {
                    buffer[uprv_strlen(buffer)-1] = '\0';
                }
                if(buffer[0] == '"') {
                    uprv_strcpy(buffer, buffer+1);
                }
            } else if(quote > 0) { /* add quotes */
                if(l->str[0] != '"') {
                    uprv_strcpy(buffer, "\"");
                    uprv_strncat(buffer, l->str,1020);
                }
                if(l->str[uprv_strlen(l->str)-1] != '"') {
                    uprv_strcat(buffer, "\"");
                }
            }
            T_FileStream_write(s, buffer, (int32_t)uprv_strlen(buffer));

            ln += (int32_t)uprv_strlen(l->str);
        }

        if(l->next && delim)
        {
            if(ln > 60 && brk) {
                ln  = 0;
                T_FileStream_write(s, brk, (int32_t)uprv_strlen(brk));
            }
            T_FileStream_write(s, delim, (int32_t)uprv_strlen(delim));
        }
        l = l->next;
    }
    return NULL;
}


const char *pkg_writeCharList(FileStream *s, CharList *l, const char *delim, int32_t quote)
{
    char buffer[1024];
    while(l != NULL)
    {
        if(l->str)
        {
            uprv_strncpy(buffer, l->str, 1023);
            buffer[1023]=0;
            if(uprv_strlen(l->str) >= 1023)
            {
                fprintf(stderr, "%s:%d: Internal error, line too long (greater than 1023 chars)\n",
                        __FILE__, __LINE__);
                exit(0);
            }
            if(quote < 0) { /* remove quotes */
                if(buffer[uprv_strlen(buffer)-1] == '"') {
                    buffer[uprv_strlen(buffer)-1] = '\0';
                }
                if(buffer[0] == '"') {
                    uprv_strcpy(buffer, buffer+1);
                }
            } else if(quote > 0) { /* add quotes */
                if(l->str[0] != '"') {
                    uprv_strcpy(buffer, "\"");
                    uprv_strcat(buffer, l->str);
                }
                if(l->str[uprv_strlen(l->str)-1] != '"') {
                    uprv_strcat(buffer, "\"");
                }
            }
            T_FileStream_write(s, buffer, (int32_t)uprv_strlen(buffer));
        }

        if(l->next && delim)
        {
            T_FileStream_write(s, delim, (int32_t)uprv_strlen(delim));
        }
        l = l->next;
    }
    return NULL;
}


/*
 * Count items . 0 if null
 */
uint32_t pkg_countCharList(CharList *l)
{
  uint32_t c = 0;
  while(l != NULL)
  {
    c++;
    l = l->next;
  }

  return c;
}

/*
 * Prepend string to CharList
 */
CharList *pkg_prependToList(CharList *l, const char *str)
{
  CharList *newList;
  newList = uprv_malloc(sizeof(CharList));

  /* test for NULL */
  if(newList == NULL) {
    return NULL;
  }

  newList->str = str;
  newList->next = l;
  return newList;
}

/*
 * append string to CharList. *end or even end can be null if you don't
 * know it.[slow]
 * Str is adopted!
 */
CharList *pkg_appendToList(CharList *l, CharList** end, const char *str)
{
  CharList *endptr = NULL, *tmp;

  if(end == NULL)
  {
    end = &endptr;
  }

  /* FIND the end */
  if((*end == NULL) && (l != NULL))
  {
    tmp = l;
    while(tmp->next)
    {
      tmp = tmp->next;
    }

    *end = tmp;
  }

  /* Create a new empty list and append it */
  if(l == NULL)
    {
      l = pkg_prependToList(NULL, str);
    }
  else
    {
      (*end)->next = pkg_prependToList(NULL, str);
    }

  /* Move the end pointer. */
  if(*end)
    {
      (*end) = (*end)->next;
    }
  else
    {
      *end = l;
    }

  return l;
}

char * convertToNativePathSeparators(char *path) {
#if defined(U_MAKE_IS_NMAKE)
    char *itr;
    while ((itr = uprv_strchr(path, U_FILE_ALT_SEP_CHAR))) {
        *itr = U_FILE_SEP_CHAR;
    }
#endif
    return path;
}

CharList *pkg_appendUniqueDirToList(CharList *l, CharList** end, const char *strAlias) {
    char aBuf[1024];
    char *rPtr;
    rPtr = uprv_strrchr(strAlias, U_FILE_SEP_CHAR);
    if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) {
        char *aPtr = uprv_strrchr(strAlias, U_FILE_ALT_SEP_CHAR);
        if(!rPtr || /* regular char wasn't found or.. */
            (aPtr && (aPtr > rPtr)))
        { /* alt ptr exists and is to the right of r ptr */
            rPtr = aPtr; /* may copy NULL which is OK */
        }
    }
    if(!rPtr) {
        return l; /* no dir path */
    }
    if((rPtr-strAlias) >= UPRV_LENGTHOF(aBuf)) {
        fprintf(stderr, "## ERR: Path too long [%d chars]: %s\n", (int)sizeof(aBuf), strAlias);
        return l;
    }
    strncpy(aBuf, strAlias,(rPtr-strAlias));
    aBuf[rPtr-strAlias]=0;  /* no trailing slash */
    convertToNativePathSeparators(aBuf);

    if(!pkg_listContains(l, aBuf)) {
        return pkg_appendToList(l, end, uprv_strdup(aBuf));
    } else {
        return l; /* already found */
    }
}

#if 0
static CharList *
pkg_appendFromStrings(CharList *l, CharList** end, const char *s, int32_t len)
{
  CharList *endptr = NULL;
  const char *p;
  char *t;
  const char *targ;
  if(end == NULL) {
    end = &endptr;
  }

  if(len==-1) {
    len = uprv_strlen(s);
  }
  targ = s+len;

  while(*s && s<targ) {
    while(s<targ&&isspace(*s)) s++;
    for(p=s;s<targ&&!isspace(*p);p++);
    if(p!=s) {
      t = uprv_malloc(p-s+1);
      uprv_strncpy(t,s,p-s);
      t[p-s]=0;
      l=pkg_appendToList(l,end,t);
      fprintf(stderr, " P %s\n", t);
    }
    s=p;
  }

  return l;
}
#endif


/*
 * Delete list
 */
void pkg_deleteList(CharList *l)
{
  CharList *tmp;
  while(l != NULL)
  {
    uprv_free((void*)l->str);
    tmp = l;
    l = l->next;
    uprv_free(tmp);
  }
}

UBool  pkg_listContains(CharList *l, const char *str)
{
  for(;l;l=l->next){
    if(!uprv_strcmp(l->str, str)) {
      return true;
    }
  }

  return false;
}
