// findthis.c
// Take some input file(s), perhaps XML, and filter by, up to two, "tag" like filters, and then a string to search for.  
// Output detail and totals as a report.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <search.h>

char filter1[201]="\0";
char filter2[201]="\0";
char searchstring[201]="\0";

int cmpfunc(const void *a, const void *b) { 
  return strcmp((char *)a, (char *)b);
}

int file_exists(char *infile) {
  FILE *infil = fopen(infile, "r");
  if (infil) {
   fclose(infil);
   return 1;
  }
  return 0;
}

void readText(char *infile) {
  FILE *infil = fopen(infile, "r");
  char spareline[301], line[301] = " \0", *pch, thisfind[201]="\0", thischar[2]=" \0";
  int found=0;
  int i=1, arrc=0;
  char arr[501][21];
  //arr = (char**)calloc(501, 21); 
  while (line[0] >= 32) {
    if (fgets(line, 300, infil) != NULL) {
      if (line[0] >= 32) {
        found=0;
        if (strstr(line, "\n")) {
         *strstr(line, "\n") = 0;
        }
        if (*filter2 > 0 && *filter1 > 0) {
         if (strstr(line, filter1) || strstr(line, filter2)) found = 1;
         //printf("A %d: %s %s %s", found, line, filter1, filter2);
        } else if (*filter1 > 0) {
         if (strstr(line, filter1)) found = 1;
          //printf("B %d: %s", found, line);
       } else if (*filter2 > 0) {
         if (strstr(line, filter2)) found = 1;
         //printf("C %d: %s", found, line);
        }
        if (searchstring[0] > 0 && found != 0) {
         found = 0;
         if (strstr(line, searchstring)) found = 1;
        }
        if (found != 0) {
         pch = strstr(line, searchstring);
         while (pch) {
           //*pch = 0;
           pch+=strlen(searchstring);
           strcpy(thisfind, searchstring);
           while (*pch != 32) {
             thischar[0] = *pch;
             strcat(thisfind, thischar);
             pch++;
           }
           arrc++;
           //if (arrc > 1) realloc((char **)arr, (size_t)arrc); 
           strcpy((char *)arr[arrc - 1], thisfind);
           sprintf(spareline, "%s", pch);
           strcpy(line, spareline);
           pch = strstr(line, searchstring);
         }
        }
      }
      strcpy(line, "x\0");
    } else {
      line[0] = 0;
    }
  }
  fclose(infil);
  if (arrc > 0) {
   printf("In file %s we have found search string '%s' %ld times, as sorted below ... %s %s\n", infile, searchstring, arrc, filter1, filter2);
   qsort(arr, (size_t)arrc, sizeof(arr[0]), cmpfunc);
   for (i=0; i<arrc; i++) {
     printf("%s\n", (char *)arr[i]);
   }
  }
  //free(arr);
}


int main(int argc, char *argv[]) {
 char inname[301];
 int j=1, jj=(argc - 1), k=1, m=argc, myinteractive=0;
 char msg[201]="Please use findthis.exe [[filter1] [filter2]] [searchstring] [[file1] [file2] ... ]\0";
       
 if (argv[0]) {
  if (!strstr(argv[jj], ".") && jj >= 1) {
   myinteractive = 1;
   if (jj == 3) {
    strcpy(searchstring, argv[jj]);
    strcpy(filter2, argv[jj - 1]);
    strcpy(filter1, argv[jj - 2]);
   } else if (jj == 2) {
    strcpy(searchstring, argv[jj]);
    strcpy(filter1, argv[jj - 1]);
   } else if (jj == 1) {
    strcpy(searchstring, argv[jj]);
   } else {
    printf("%s", msg);
    return 0;
   }  
  } else if (file_exists(argv[jj]) == 0) {
   printf("%s", msg);
   return 0;
  } else {
   while (file_exists(argv[jj]) != 0 && strstr(argv[jj], ".") && jj >= 1) {
     jj--;
   }
  }
  if (jj <= 0) {
   printf("%s", msg);
   return 0;
  } else if (jj == 3) {
   strcpy(searchstring, argv[jj]);
   strcpy(filter2, argv[jj - 1]);
   strcpy(filter1, argv[jj - 2]);
  } else if (jj == 2) {
   strcpy(searchstring, argv[jj]);
   strcpy(filter1, argv[jj - 1]);
  } else if (jj == 1) {
   strcpy(searchstring, argv[jj]);
  }
 } else {
  printf("%s", msg);
  return 0;
 }
 
 if (myinteractive != 0) {
  printf("Enter name for file: ");
  fgets(inname, 300, stdin); 
  sscanf(inname, "%[^\n]s", inname); 
  readText(inname);
 } else {
  jj++;
  while (file_exists(argv[jj]) != 0) {
    strcpy(inname, argv[jj]); 
    readText(inname);
    jj++;
    if (jj >= argc) return 0;
  }
 }
 return 0;
}
