/**
 * thrift - a lightweight cross-language rpc/serialization tool
 *
 * This file contains the main compiler engine for Thrift, which invokes the
 * scanner/parser to build the thrift object tree. The interface generation
 * code for each language lives in a file by the language name.
 *
 * @author Mark Slee <mcslee@facebook.com>
 */

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string>

// Careful: must include globals first
#include "globals.h"

#include "main.h"
#include "parse/t_program.h"
#include "generate/t_cpp_generator.h"
#include "generate/t_java_generator.h"
#include "generate/t_php_generator.h"

using namespace std;

/** Global program tree */
t_program* g_program;

/** Global debug state */
int g_debug = 0;

/** Global time string */
char* g_time_str;


/**
 * Report an error to the user. This is called yyerror for historical
 * reasons (lex and yacc expect the error reporting routine to be called
 * this). Call this function to report any errors to the user.
 * yyerror takes printf style arguments.
 *
 * @param fmt C format string followed by additional arguments
 */
void yyerror(char* fmt, ...) {
  va_list args;
  fprintf(stderr,
          "\n!!! Error: line %d (last token was '%s')",
          yylineno,
          yytext);
  fprintf(stderr, "\n!!! ");

  va_start(args, fmt);
  vfprintf(stderr, fmt, args);
  va_end(args);

  fprintf(stderr, "\n");
}

/**
 * Prints a debug message from the parser.
 *
 * @param fmt C format string followed by additional arguments
 */
void pdebug(char* fmt, ...) {
  if (g_debug == 0) {
    return;
  }
  va_list args;
  printf("[Parse] ");
  va_start(args, fmt);
  vprintf(fmt, args);
  va_end(args);
  printf("\n");
}

/**
 * Prints a failure message and exits
 *
 * @param fmt C format string followed by additional arguments
 */
void failure(char* fmt, ...) {
  va_list args; 
  fprintf(stderr, "\n!!! Failure: ");
  va_start(args, fmt);
  vfprintf(stderr, fmt, args);
  va_end(args);
  printf("\n");
  exit(1);
}

/**
 * Diplays the usage message and then exits with an error code.
 */
void usage() {
  fprintf(stderr, "Usage: thrift [options] file\n");
  fprintf(stderr, "Options:\n");
  fprintf(stderr, "  -cpp    Generate C++ output files\n");
  fprintf(stderr, "  -java   Generate Java output files\n");
  fprintf(stderr, "  -php    Generate PHP output files\n");
  //fprintf(stderr, "  -python Generate Python output files\n");
  fprintf(stderr, "  -d      Print parse debugging to standard output\n");
  exit(1);
}

/**
 * Parse it up.. then spit it back out, in pretty much every language
 */
int main(int argc, char** argv) {
  int i;
  bool gen_cpp = false;
  bool gen_java = false;
  bool gen_php = false;

  // Setup time string
  time_t now = time(NULL);
  g_time_str = ctime(&now);

  // Check for necessary arguments
  if (argc < 2) {
    usage();
  }

  for (i = 1; i < argc-1; i++) {
    if (strcmp(argv[i], "-d") == 0) {
      g_debug = 1;
    } else if (strcmp(argv[i], "-cpp") == 0) {
      gen_cpp = true;
    } else if (strcmp(argv[i], "-java") == 0) {
      gen_java = true;
    } else if (strcmp(argv[i], "-php") == 0) {
      gen_php = true;
    } else {
      fprintf(stderr, "!!! Unrecognized option: %s\n", argv[i]);
      usage();
    }
  }
  
  if (!gen_cpp && !gen_java && !gen_php) {
    fprintf(stderr, "!!! No output language(s) specified\n\n");
    usage();
  }
  
  // Open input file
  char* input_file = argv[i];
  yyin = fopen(input_file, "r");
  if (yyin == 0) {
    failure("Could not open input file: \"%s\"", input_file);
  }
  
  // Extract program name by dropping directory and .thrift from filename
  string name = input_file;
  string::size_type slash = name.rfind("/");
  if (slash != string::npos) {
    name = name.substr(slash+1);
  }
  string::size_type dot = name.find(".");
  if (dot != string::npos) {
    name = name.substr(0, dot);
  }
  
  // Parse it
  g_program = new t_program(name);

  if (yyparse() != 0) {
    failure("Parser error.");
  }

  // Generate code
  try {
    if (gen_cpp) {
      t_cpp_generator* cpp = new t_cpp_generator();
      cpp->generate_program(g_program);
      delete cpp;
    }

    if (gen_java) {
      t_java_generator* java = new t_java_generator();
      java->generate_program(g_program);
      delete java;
    }

    if (gen_php) {
      t_php_generator* php = new t_php_generator();
      php->generate_program(g_program);
      delete php;
    }
  } catch (string s) {
    printf("Error: %s\n", s.c_str());
  } catch (const char* exc) {
    printf("Error: %s\n", exc);
  }

  // Clean up
  delete g_program;

  // Finished
  return 0;
}
