/**
 * 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, "  -phpi   Generate PHP inlined 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;
  bool php_inline = 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;
      php_inline = false;
    } else if (strcmp(argv[i], "-phpi") == 0) {
      gen_php = true;
      php_inline = 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_inline);
      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;
}
