#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include <unistd.h> // for getopt
#include <stdexcept> // for std::stoi and exceptions

using namespace std;

#include "SysYLexer.h"
#include "SysYParser.h"
using namespace antlr4;

#include "SysYIRGenerator.h"
#include "SysYIRPrinter.h"
#include "SysYIROptPre.h"
#include "RISCv64Backend.h"
#include "SysYIRAnalyser.h"
#include "DeadCodeElimination.h"
#include "AddressCalculationExpansion.h"
#include "Mem2Reg.h"
#include "Reg2Mem.h"

using namespace sysy;

int DEBUG = 0;
int DEEPDEBUG = 0;

static string argStopAfter;
static string argInputFile;
static bool argFormat = false; // 目前未使用，但保留
static string argOutputFilename;
static int optLevel = 0; // 优化级别，默认为0 (不加-O参数时)

void usage(int code) {
  const char *msg = "Usage: sysyc [options] inputfile\n\n"
                    "Supported options:\n"
                    "  -h \tprint help message and exit\n"
                    "  -f \tpretty-format the input file\n"
                    "  -s {ast,ir,asm,llvmir,asmd,ird}\tstop after generating AST/IR/Assembly\n"
                    "  -S \tcompile to assembly (.s file)\n"
                    "  -o <file>\tplace the output into <file>\n"
                    "  -O<level>\tenable optimization at <level> (e.g., -O0, -O1)\n";
  cerr << msg;
  exit(code);
}

void parseArgs(int argc, char **argv) {
  const char *optstr = "hfs:So:O:"; 
  int opt = 0;

  while ((opt = getopt(argc, argv, optstr)) != -1) {
    switch (opt) {
    case 'h':
      usage(EXIT_SUCCESS);
      break;
    case 'f':
      argFormat = true;
      break;
    case 's':
      argStopAfter = optarg;
      break;
    case 'S':
      argStopAfter = "asm";
      break;
    case 'o':
      argOutputFilename = optarg;
      break;
    case 'O':
      try {
        optLevel = std::stoi(optarg);
        if (optLevel < 0) {
          cerr << "Error: Optimization level must be non-negative." << endl;
          usage(EXIT_FAILURE);
        }
      } catch (const std::invalid_argument& ia) {
        cerr << "Error: Invalid argument for -O: " << optarg << endl;
        usage(EXIT_FAILURE);
      } catch (const std::out_of_range& oor) {
        cerr << "Error: Optimization level out of range: " << optarg << endl;
        usage(EXIT_FAILURE);
      }
      break;
    default: /* '?' */
      usage(EXIT_FAILURE);
    }
  }

  if (optind >= argc) {
    usage(EXIT_FAILURE);
  }
  argInputFile = argv[optind];
}

int main(int argc, char **argv) {
  parseArgs(argc, argv);

  // 1. 打开输入文件
  ifstream fin(argInputFile);
  if (not fin.is_open()) {
    cerr << "Failed to open input file: " << argInputFile << endl;
    return EXIT_FAILURE;
  }

  // 2. 解析 SysY 源代码到 AST (前端)
  ANTLRInputStream input(fin);
  SysYLexer lexer(&input);
  CommonTokenStream tokens(&lexer);
  SysYParser parser(&tokens);
  auto moduleAST = parser.compUnit();

  // 如果指定停止在 AST 阶段，则打印并退出
  if (argStopAfter == "ast") {
    cout << moduleAST->toStringTree(true) << '\n';
    return EXIT_SUCCESS;
  }

  // 3. 遍历 AST 生成 IR (中端开始)
  SysYIRGenerator generator;
  generator.visitCompUnit(moduleAST);
  auto moduleIR = generator.get(); 
  auto builder = generator.getBuilder(); // 获取 IRBuilder 实例

  // 4. 执行 IR 优化 pass
  // 无论最终输出是 IR 还是 ASM，只要不是停止在 AST 阶段，都会进入此优化流程。
  // optLevel = 0 时，执行默认优化。
  // optLevel >= 1 时，执行默认优化 + 额外的 -O1 优化。
  if (DEBUG) cout << "Applying middle-end optimizations (level -O" << optLevel << ")...\n";

  // 设置 DEBUG 模式（如果指定了 'ird'）
  if (argStopAfter == "ird") {
    DEBUG = 1; // 这里可能需要更精细地控制 DEBUG 的开启时机和范围
  }
  // 默认优化 pass (在所有优化级别都会执行)
  SysYOptPre optPre(moduleIR, builder);
  optPre.SysYOptimizateAfterIR(); 

  ControlFlowAnalysis cfa(moduleIR);
  cfa.init();
  ActiveVarAnalysis ava;
  ava.init(moduleIR);

  if (DEBUG) {
    cout << "=== After CFA & AVA (Default) ===\n";
    SysYPrinter(moduleIR).printIR(); // 临时打印器用于调试
  }
  AddressCalculationExpansion ace(moduleIR, builder);
  if (ace.run()) {
      if (DEBUG) cout << "AddressCalculationExpansion made changes.\n";
      // 如果 ACE 改变了IR，并且 DEBUG 模式开启，可以考虑打印IR
      if (DEBUG) {
          cout << "=== After AddressCalculationExpansion ===\n";
          SysYPrinter(moduleIR).printIR();
      }
  } else {
      if (DEBUG) cout << "AddressCalculationExpansion made no changes.\n";
  }


  // 根据优化级别，执行额外的优化 pass
  if (optLevel >= 1) { 
    if (DEBUG) cout << "Applying additional -O" << optLevel << " optimizations...\n";
    // 放置 -O1 及其以上级别要启用的额外优化 pass
    // 例如：
    // MyNewOptimizationPass newOpt(moduleIR, builder);
    // newOpt.run();
    
    // 占位符注释，替换为你的具体优化 pass
    // cout << "--- Additional Pass: MyCustomOpt1 ---" << endl;
    // MyCustomOpt1 opt1_pass(moduleIR, builder);
    // opt1_pass.run();

    // cout << "--- Additional Pass: MyCustomOpt2 ---" << endl;
    // MyCustomOpt2 opt2_pass(moduleIR, builder, &cfa); // 假设需要CFA
    // opt2_pass.run();
    // ... 更多 -O1 特有的优化
    DeadCodeElimination dce(moduleIR, &cfa, &ava);
    dce.runDCEPipeline();
    if (DEBUG) {
      cout << "=== After 1st DCE (Default) ===\n";
      SysYPrinter(moduleIR).printIR();
    }

    Mem2Reg mem2reg(moduleIR, builder, &cfa, &ava);
    mem2reg.mem2regPipeline();
    if (DEBUG) {
      cout << "=== After Mem2Reg (Default) ===\n";
      SysYPrinter(moduleIR).printIR();
    }

    Reg2Mem reg2mem(moduleIR, builder);
    reg2mem.DeletePhiInst();
    if (DEBUG) {
      cout << "=== After Reg2Mem (Default) ===\n";
      SysYPrinter(moduleIR).printIR();
    }

    dce.runDCEPipeline(); // 第二次 DCE (默认)
    if (DEBUG) {
      cout << "=== After 2nd DCE (Default) ===\n";
      SysYPrinter(moduleIR).printIR();
    }
  } else {
    if (DEBUG) cout << "No additional middle-end optimizations applied for -O" << optLevel << ".\n";
  }

  // 5. 根据 argStopAfter 决定后续操作
  // a) 如果指定停止在 IR 阶段，则打印最终 IR 并退出
  if (argStopAfter == "ir" || argStopAfter == "ird") {
    // 打印最终 IR
    cout << "=== Final IR ===\n";
    SysYPrinter printer(moduleIR); // 在这里创建打印器，因为可能之前调试时用过临时打印器
    printer.printIR();
    return EXIT_SUCCESS;
  }

  // b) 如果未停止在 IR 阶段，则继续生成汇编 (后端)
  // 设置 DEBUG 模式（如果指定了 'asmd'）
  if (argStopAfter == "asmd") {
    DEBUG = 1;
    // DEEPDEBUG = 1;
  }
  sysy::RISCv64CodeGen codegen(moduleIR); // 传入优化后的 moduleIR
  string asmCode = codegen.code_gen();

  // 如果指定停止在 ASM 阶段，则打印/保存汇编并退出
  if (argStopAfter == "asm" || argStopAfter == "asmd") {
    if (!argOutputFilename.empty()) {
      ofstream fout(argOutputFilename);
      if (not fout.is_open()) {
        cerr << "Failed to open output file: " << argOutputFilename << endl;
        return EXIT_FAILURE;
      }
      fout << asmCode << endl;
      fout.close();
    } else {
      cout << asmCode << endl;
    }
    return EXIT_SUCCESS;
  }

  // 如果没有匹配到任何 -s 或 -S 选项，即意味着需要生成完整可执行文件（未来的功能）
  // 目前，可以简单退出，或者打印一条提示
  cout << "Compilation completed. No output specified (neither -s nor -S). Exiting.\n";
  // return EXIT_SUCCESS; // 或者这里调用一个链接器生成可执行文件

  return EXIT_SUCCESS; 
}