/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed 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. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

/* Theta/speech.c - Speech library
 * For the Theta text to speech package
 * Maintained by Dave Mielke <dave@mielke.cc>
 */

#include "prologue.h"

#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <sys/wait.h>

#include "log.h"
#include "parse.h"

typedef enum {
  PARM_AGE,
  PARM_GENDER,
  PARM_LANGUAGE,
  PARM_NAME,
  PARM_PITCH
} DriverParameter;
#define SPKPARMS "age", "gender", "language", "name", "pitch"

#include "spk_driver.h"

struct theta_sfx_block_ops { /* used but not defined in header */
  char dummy;
};
#include <theta.h>

static cst_voice *voice = NULL;
static pid_t child = -1;
static int pipeDescriptors[2];
static const int *pipeOutput = &pipeDescriptors[0];
static const int *pipeInput = &pipeDescriptors[1];

static void
initializeTheta (void) {
  static int initialized = 0;
  if (!initialized) {
    {
      const char *directory = THETA_ROOT "/voices";
      setenv("THETA_VOXPATH", directory, 0);
    }

    setenv("THETA_HOME", THETA_ROOT, 0);
    theta_init(NULL);
    initialized = 1;
  }
}

static void
loadVoice (theta_voice_desc *descriptor) {
  if ((voice = theta_load_voice(descriptor))) {
    logMessage(LOG_INFO, "Voice: %s(%s,%d)",
               theta_voice_human(voice),
               theta_voice_gender(voice),
               theta_voice_age(voice));
  } else {
    logMessage(LOG_WARNING, "Voice load error: %s [%s]",
               descriptor->human, descriptor->voxname);
  }
}

static int
doChild (void) {
  FILE *stream = fdopen(*pipeOutput, "r");
  char buffer[0X400];
  char *line;
  while ((line = fgets(buffer, sizeof(buffer), stream))) {
    theta_tts(line, voice);
  }
  return 0;
}

static void
spk_say (SpeechSynthesizer *spk, const unsigned char *buffer, size_t length, size_t count, const unsigned char *attributes) {
  if (voice) {
    if (child != -1) goto ready;

    if (pipe(pipeDescriptors) != -1) {
      if ((child = fork()) == -1) {
        logSystemError("fork");
      } else if (child == 0) {
        _exit(doChild());
      } else
      ready: {
        unsigned char text[length + 1];
        memcpy(text, buffer, length);
        text[length] = '\n';
        write(*pipeInput, text, sizeof(text));
        return;
      }

      close(*pipeInput);
      close(*pipeOutput);
    } else {
      logSystemError("pipe");
    }
  }
}

static void
spk_mute (SpeechSynthesizer *spk) {
  if (child != -1) {
    close(*pipeInput);
    close(*pipeOutput);

    kill(child, SIGKILL);
    waitpid(child, NULL, 0);
    child = -1;
  }
}

static void
spk_setVolume (SpeechSynthesizer *spk, unsigned char setting) {
  theta_set_rescale(voice, getFloatSpeechVolume(setting), NULL);
}

static void
spk_setRate (SpeechSynthesizer *spk, unsigned char setting) {
  theta_set_rate_stretch(voice, 1.0/getFloatSpeechRate(setting), NULL);
}

static int
spk_construct (SpeechSynthesizer *spk, char **parameters) {
  theta_voice_search criteria;

  memset(&criteria, 0, sizeof(criteria));
  initializeTheta();

  spk->setVolume = spk_setVolume;
  spk->setRate = spk_setRate;

  if (*parameters[PARM_GENDER]) {
    const char *const choices[] = {"male", "female", "neuter", NULL};
    unsigned int choice;
    if (validateChoice(&choice, parameters[PARM_GENDER], choices)) {
      criteria.gender = (char *)choices[choice];
    } else {
      logMessage(LOG_WARNING, "%s: %s", "invalid gender specification", parameters[PARM_GENDER]);
    }
  }

  if (*parameters[PARM_LANGUAGE]) criteria.lang = parameters[PARM_LANGUAGE];

  if (*parameters[PARM_AGE]) {
    const char *word = parameters[PARM_AGE];
    int value;
    int younger;
    static const int minimumAge = 1;
    static const int maximumAge = 99;
    if ((younger = word[0] == '-') && word[1]) ++word;
    if (validateInteger(&value, word, &minimumAge, &maximumAge)) {
      if (younger) value = -value;
      criteria.age = value;
    } else {
      logMessage(LOG_WARNING, "%s: %s", "invalid age specification", word);
    }
  }

  {
    const char *name = parameters[PARM_NAME];
    if (name && (*name == '/')) {
      theta_voice_desc *descriptor = theta_try_voxdir(name, &criteria);
      if (descriptor) {
        loadVoice(descriptor);
        theta_free_voice_desc(descriptor);
      }
    } else {
      theta_voice_desc *descriptors = theta_enum_voices(theta_voxpath, &criteria);
      if (descriptors) {
        theta_voice_desc *descriptor;
        for (descriptor=descriptors; descriptor; descriptor=descriptor->next) {
          if (*name)
            if (strcasecmp(name, descriptor->human) != 0)
              continue;
          loadVoice(descriptor);
          if (voice) break;
        }
        theta_free_voicelist(descriptors);
      }
    }
  }

  if (voice) {
    {
      float pitch = 0.0;
      static const float minimumPitch = -2.0;
      static const float maximumPitch = 2.0;
      if (validateFloat(&pitch, parameters[PARM_PITCH], &minimumPitch, &maximumPitch)) {
        theta_set_pitch_shift(voice, pitch, NULL);
      } else {
        logMessage(LOG_WARNING, "%s: %s", "invalid pitch shift specification", parameters[PARM_PITCH]);
      }
    }

    logMessage(LOG_INFO, "Theta Engine: version %s", theta_version);
    return 1;
  }

  logMessage(LOG_WARNING, "No voices found.");
  return 0;
}

static void
spk_destruct (SpeechSynthesizer *spk) {
  spk_mute(spk);

  if (voice) {
    theta_unload_voice(voice);
    voice = NULL;
  }
}
