/* cut.c - Cut from a file.
 *
 * Copyright 2012 Ranjan Kumar <ranjankumar.bth@gmail.com>
 * Copyright 2012 Kyungwan Han <asura321@gmail.com>
 *
 * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html
 *
 * TODO: cleanup

USE_CUT(NEWTOY(cut, "b:|c:|f:|d:sn[!cbf]", TOYFLAG_USR|TOYFLAG_BIN))

config CUT
  bool "cut"
  default y
  help
    usage: cut OPTION... [FILE]...

    Print selected parts of lines from each FILE to standard output.

    -b LIST	select only these bytes from LIST.
    -c LIST	select only these characters from LIST.
    -f LIST	select only these fields.
    -d DELIM	use DELIM instead of TAB for field delimiter.
    -s	do not print lines not containing delimiters.
    -n	don't split multibyte characters (Ignored).
*/
#define FOR_cut
#include "toys.h"

GLOBALS(
  char *delim;
  char *flist;
  char *clist;
  char *blist;

  void *slist_head;
  unsigned nelem;
  void (*do_cut)(int fd);
)

struct slist {
  struct slist *next;
  int start, end;
};

static void add_to_list(int start, int end)
{
  struct slist *current, *head_ref, *temp1_node;

  head_ref = TT.slist_head;
  temp1_node = xzalloc(sizeof(struct slist));
  temp1_node->start = start;
  temp1_node->end = end;

  /* Special case for the head end */
  if (!head_ref || head_ref->start >= start) { 
      temp1_node->next = head_ref; 
      head_ref = temp1_node;
  } else { 
    /* Locate the node before the point of insertion */   
    current = head_ref;   
    while (current->next && current->next->start < temp1_node->start)
        current = current->next;
    temp1_node->next = current->next;   
    current->next = temp1_node;
  }
  TT.slist_head = head_ref;
}

// parse list and add to slist.
static void parse_list(char *list)
{
  for (;;) {
    char *ctoken = strsep(&list, ","), *dtoken;
    int start = 0, end = INT_MAX;

    if (!ctoken) break;
    if (!*ctoken) continue;

    // Get start position.
    if (*(dtoken = strsep(&ctoken, "-"))) {
      start = atolx_range(dtoken, 0, INT_MAX);
      start = (start?(start-1):start);
    }

    // Get end position.
    if (!ctoken) end = -1; //case e.g. 1,2,3
    else if (*ctoken) {//case e.g. N-M
      end = atolx_range(ctoken, 0, INT_MAX);
      if (!end) end = INT_MAX;
      end--;
      if(end == start) end = -1;
    }
    add_to_list(start, end);
    TT.nelem++;
  }
  // if list is missing in command line.
  if (!TT.nelem) error_exit("missing positions list");
}

/*
 * retrive data from the file/s.
 */
static void get_data(void)
{
  char **argv = toys.optargs; //file name.
  toys.exitval = EXIT_SUCCESS;

  if(!*argv) TT.do_cut(0); //for stdin
  else {
    for(; *argv; ++argv) {
      if(strcmp(*argv, "-") == 0) TT.do_cut(0); //for stdin
      else {
        int fd = open(*argv, O_RDONLY, 0);
        if (fd < 0) {//if file not present then continue with other files.
          perror_msg_raw(*argv);
          continue;
        }
        TT.do_cut(fd);
        xclose(fd);
      }
    }
  }
}

// perform cut operation on the given delimiter.
static void do_fcut(int fd)
{
  char *buff, *pfield = 0, *delimiter = TT.delim;

  for (;;) {
    unsigned cpos = 0;
    int start, ndelimiters = -1;
    int  nprinted_fields = 0;
    struct slist *temp_node = TT.slist_head;

    free(pfield);
    pfield = 0;

    if (!(buff = get_line(fd))) break;

    //does line have any delimiter?.
    if (strrchr(buff, (int)delimiter[0]) == NULL) {
      //if not then print whole line and move to next line.
      if (!(toys.optflags & FLAG_s)) xputs(buff);
      continue;
    }

    pfield = xzalloc(strlen(buff) + 1);

    if (temp_node) {
      //process list on each line.
      while (cpos < TT.nelem && buff) {
        if (!temp_node) break;
        start = temp_node->start;
        do {
          char *field = 0;

          //count number of delimeters per line.
          while (buff) {
            if (ndelimiters < start) {
              ndelimiters++;
              field = strsep(&buff, delimiter);
            } else break;
          }
          //print field (if not yet printed).
          if (!pfield[ndelimiters]) {
            if (ndelimiters == start) {
              //put delimiter.
              if (nprinted_fields++ > 0) xputc(delimiter[0]);
              if (field) fputs(field, stdout);
              //make sure this field won't print again.
              pfield[ndelimiters] = (char) 0x23; //put some char at this position.
            }
          }
          start++;
          if ((temp_node->end < 0) || !buff) break;          
        } while(start <= temp_node->end);
        temp_node = temp_node->next;
        cpos++;
      }
    }
    xputc('\n');
  }
}

// perform cut operation char or byte.
static void do_bccut(int fd)
{
  char *buff;

  while ((buff = get_line(fd)) != NULL) {
    unsigned cpos = 0;
    int buffln = strlen(buff);
    char *pfield = xzalloc(buffln + 1);
    struct slist *temp_node = TT.slist_head;

    if (temp_node != NULL) {
      while (cpos < TT.nelem) {
        int start;

        if (!temp_node) break;
        start = temp_node->start;
        while (start < buffln) {
          //to avoid duplicate field printing.
          if (pfield[start]) {
              if (++start <= temp_node->end) continue;
              temp_node = temp_node->next;
              break;
          } else {
            //make sure this field won't print again.
            pfield[start] = (char) 0x23; //put some char at this position.
            xputc(buff[start]);
          }
          if (++start > temp_node->end) {
            temp_node = temp_node->next;
            break;
          }
        }
        cpos++;
      }
      xputc('\n');
    }
    free(pfield);
    pfield = NULL;
  }
}

void cut_main(void)
{
  char delimiter = '\t'; //default delimiter.
  char *list;

  TT.nelem = 0;
  TT.slist_head = NULL;

  //Get list and assign the function.
  if (toys.optflags & FLAG_f) {
    list = TT.flist;
    TT.do_cut = do_fcut;
  } else if (toys.optflags & FLAG_c) {
    list = TT.clist;
    TT.do_cut = do_bccut;
  } else {
    list = TT.blist;
    TT.do_cut = do_bccut;
  }

  if (toys.optflags & FLAG_d) {
    //delimiter must be 1 char.
    if(TT.delim[0] && TT.delim[1])
      perror_exit("the delimiter must be a single character");
    delimiter = TT.delim[0];
  }

  if(!(toys.optflags & FLAG_d) && (toys.optflags & FLAG_f)) {
    TT.delim = xzalloc(2);
    TT.delim[0] = delimiter;
  }
  
  //when field is not specified, cutting has some special handling.
  if (!(toys.optflags & FLAG_f)) {
    if (toys.optflags & FLAG_s)
      perror_exit("suppressing non-delimited lines operating on fields");
    if (delimiter != '\t')
      perror_exit("an input delimiter may be specified only when operating on fields");
  }

  parse_list(list);
  get_data();
  if (!(toys.optflags & FLAG_d) && (toys.optflags & FLAG_f)) {
    free(TT.delim);
    TT.delim = NULL;
  }
  llist_traverse(TT.slist_head, free);
}
