/* ptexindy.c: An index processor for platex and uplatex by using xindy

   Copyright 2014 Akira Kakuto.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this library; if not, see <http://www.gnu.org/licenses/>.  */

/*
  ptexindy may be nearly equivalent with
  #!/bin/sh
  pxindy -M texindy -M page-ranges -L japanese -C utf8 "$@"  
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef _WIN32
#define strcasecmp _stricmp
#include <process.h>
#include <malloc.h>
#else
#include <sys/wait.h>
#ifndef WEXITSTATUS
#define WEXITSTATUS(val) ((unsigned int)(val) >> 8)
#endif
#ifndef WIFEXITED
#define WIFEXITED(val) (((val) & 255) == 0)
#endif
#endif

#define MAXARG 32

static int
x_spawn (char **cmdv)
{
  int ret;
#ifdef _WIN32
  ret = _spawnvp (_P_WAIT, *cmdv, (const char* const*)cmdv);
#else
  int i;
  i = fork ();
  if (i < 0) {
    ret = -1;
  } else if (i == 0) {
    if (execvp (*cmdv, cmdv))
      _exit (-1);
  } else {
    if (wait (&ret) == i) {
      ret = (WIFEXITED (ret) ? WEXITSTATUS (ret) : -1);
    } else {
      ret = -1;
    }
  }
#endif
  return ret;
}

static void
usage (void)
{
  printf ("Usage: ptexindy [-no-nkf] [additional xindy options] idx_file\n");
  exit (0);
}

#ifdef _WIN32
static int
is_include_space (char *s)
{
  char *p;

  if(p = strchr (s, ' '))
    return 1;
  if(p = strchr (s, '\t'))
    return 1;
  return 0;
}
#endif

int main (int argc, char *argv[])
{
  char *av[MAXARG];
  char *idxname, *p, *q;
  FILE *f;
  int  i;
  int  no_nkf = 0;

  if (argc > MAXARG - 9) {
    fprintf (stderr, "Too many arguments.\n");
    exit (1);
  }

  if (argc > 1 && (!strncmp(argv[1], "-n", 2) ||
      !strncmp(argv[1], "--n", 3))) {
    no_nkf = 1;
    argc--;
    argv++;
  }

  if (argc == 1 || (argc == 2 && (!strncmp(argv[1], "-h", 2) ||
      !strncmp(argv[1], "--h", 3)))) {
    usage ();
  }

  q = argv[argc-1];
  p = strchr (q, '.');
  if (p == NULL || strcasecmp (p, ".idx")) {
    idxname = malloc (strlen(q) + 5);
    strcpy(idxname, q);
    strcat(idxname, ".idx");
  } else {
    idxname = malloc (strlen(q) + 1);
    strcpy (idxname, q);
  }

  f = fopen(idxname, "r");
  if (f == NULL) {
    fprintf(stderr, "%s is not found.\n", idxname);
    exit (1);
  }

  fclose(f);

  if (no_nkf == 0) {
    av[0] = strdup ("nkf");
    av[1] = strdup ("-w");
    av[2] = strdup ("--overwrite");

#ifdef _WIN32
    if (is_include_space (idxname)) {
      av[3] = malloc (strlen (idxname) + 3);
      strcpy (av[3], "\"");
      strcat (av[3], idxname);
      strcat (av[3], "\"");
    } else {
      av[3] = malloc (strlen (idxname) + 1);
      strcpy (av[3], idxname);
    }
#else
    av[3] = malloc (strlen (idxname) + 1);
    strcpy (av[3], idxname);
#endif

    av[4] = NULL;

    i = x_spawn (av);

    if (i != 0) {
      fprintf(stderr, "nkf failed or it dose not exist.\n");
      fprintf(stderr, "I'll continue, since nkf is not necessary "
	      "if %s is already UTF-8 encoded.\n", idxname);
    }

    free (av[0]);
    free (av[1]);
    free (av[2]);
    free (av[3]);
  }

  av[0] = strdup("pxindy");
  av[1] = strdup("-M");
  av[2] = strdup("texindy");
  av[3] = strdup("-M");
  av[4] = strdup("page-ranges");
  av[5] = strdup("-L");
  av[6] = strdup("japanese");
  av[7] = strdup("-C");
  av[8] = strdup("utf8");

  if (argc > 2) {
    for (i = 1; i < argc-1; i++) {
#ifdef _WIN32
      if (is_include_space (argv[i])) {
        av[i+8] = malloc (strlen (argv[i]) + 3);
        strcpy (av[i+8], "\"");
        strcat (av[i+8], argv[i]);
        strcat (av[i+8], "\"");
      } else {
        av[i+8] = argv[i];
      }
#else
      av[i+8] = argv[i];
#endif
    }
  }

#ifdef _WIN32
  if (is_include_space(idxname)) {
    av[argc+7] = malloc (strlen(idxname) + 3);
    strcpy(av[argc+7], "\"");
    strcat(av[argc+7], idxname);
    strcat(av[argc+7], "\"");
  } else {
    av[argc+7] = idxname;
  }
#else
  av[argc+7] = idxname;
#endif

  av[argc+8] = NULL;

  i = x_spawn (av);
  return i;
}
