/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : idlToC++.cc                                                   */
/* Author   : Tom O'Reilly                                                  */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 02/07/2000                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "IdlParser.h"
#include "IdlToCpp.h"

int preprocess(const char *inputFile, char *tmpInputFile, 
	       char *preprocFile);

int main(int argc, char **argv)
{
  if (argc != 2) {
    fprintf(stderr, "Usage: %s idlFile\n", argv[0]);
    return 1;
  }

  char tmpFilename[256];
  char preprocFilename[256];

  // Run precompiler on input file, to process #includes...
  if (preprocess(argv[1], tmpFilename, preprocFilename) == -1) {
    return 1;
  }

  fprintf(stderr, "Processing file %s...\n", preprocFilename);

  FILE *idlFile;
  if ((idlFile = fopen(preprocFilename, "r")) == 0) {
    fprintf(stderr, "Couldn't open IDL file \"%s\"\n", preprocFilename);
    return 1;
  }

  bool parseError = false;

  IdlParser *parser = new IdlParser(idlFile);
  Interface *interface;

  while ((interface = parser->nextInterface(&parseError)) != 0) {

    if (parseError) {
      fprintf(stderr, "%s\n", parser->errorMsg());
      break;
    }

    // Generate C++ code
    IdlToCpp *idlToCpp = new IdlToCpp(interface);

    char filename[256];
    FILE *output;

    sprintf(filename, "%s.h", IdlToCpp::stubName(interface));
    if ((output = fopen(filename, "w")) == 0) {
      fprintf(stderr, "Couldn't open output file \"%s\"\n", filename);
      return 1;
    }

    idlToCpp->generateStubHeader(output);
    fclose(output);

    sprintf(filename, "%s.cc", IdlToCpp::stubName(interface));
    if ((output = fopen(filename, "w")) == 0) {
      fprintf(stderr, "Couldn't open output file \"%s\"\n", filename);
      return 1;
    }
    idlToCpp->generateStub(output);
    fclose(output);

    sprintf(filename, "%s.h", IdlToCpp::skeletonName(interface));
    if ((output = fopen(filename, "w")) == 0) {
      fprintf(stderr, "Couldn't open output file \"%s\"\n", filename);
      return 1;
    }
    idlToCpp->generateSkeletonHeader(output);
    fclose(output);

    sprintf(filename, "%s.cc", IdlToCpp::skeletonName(interface));
    if ((output = fopen(filename, "w")) == 0) {
      fprintf(stderr, "Couldn't open output file \"%s\"\n", filename);
      return 1;
    }
    idlToCpp->generateSkeleton(output);
    fclose(output);

    delete idlToCpp;

  }

  fclose(idlFile);

  char cmd[256];
  sprintf(cmd, "rm %s", tmpFilename);
  if (system(cmd) != 0) {
    fprintf(stderr, "Command \"%s\" failed\n", cmd);
    return -1;
  }

  if (parseError) {
    fprintf(stderr, "Return without deleting temporary file %s\n",
	    preprocFilename);

    // Just return. Don't remove temporary input file, so user
    // can look at errors.
    return 1;
  }
  else {
    fprintf(stderr, "Deleting preprocessed file %s...\n", preprocFilename);
    sprintf(cmd, "rm %s", preprocFilename);
    if (system(cmd) != 0) {
      fprintf(stderr, "Command \"%s\" failed\n", cmd);
      return -1;
    }

    return 0;
  }
}



int preprocess(const char *inputFile, char *tmpFile, char *outputFile)
{
  char cmd[256];

  pid_t pid = getpid();

  // Copy input file to something with ".cc" extension, so compiler can
  // deal with it.
  sprintf(tmpFile, "/tmp/%s.%d.cc", inputFile, getpid());
  sprintf(cmd, "cp %s %s", inputFile, tmpFile);
  if (system(cmd) != 0) {
    fprintf(stderr, "Command \"%s\" failed\n", cmd);
    return -1;
  }

  // Run precompiler
  sprintf(cmd, "cc -P %s", tmpFile);
  if (system(cmd) != 0) {
    fprintf(stderr, "Command \"%s\" failed\n", cmd);
    return -1;
  }

  strcpy(outputFile, tmpFile);
  char *endPtr = strrchr(outputFile, '.');
  strcpy(endPtr, ".i");

  return 0;
}

