/*
 * This file defines a signal handler used by VPR to catch SIGINT signals
 * (ctrl-C from terminal) on POSIX systems. It is only active if
 * VPR_USE_SIGACTION is defined.
 *
 * If a SIGINT occur the handler sets the 'forced_pause' flag of the VPR
 * context.  If 'forced_pause' is still true when another SIGINT occurs an
 * exception is thrown (typically ending the program).
 */
#include "vtr_log.h"
#include "vtr_time.h"

#include "vpr_signal_handler.h"
#include "vpr_exit_codes.h"
#include "vpr_error.h"
#include "globals.h"

#include "read_place.h"
#include "route_export.h"
#include <atomic>

#ifdef VPR_USE_SIGACTION
#    include <csignal>
#endif

void vpr_signal_handler(int signal);
void checkpoint();

std::atomic<int> uncleared_sigint_count(0);

#ifdef VPR_USE_SIGACTION

void vpr_install_signal_handler() {
    //Install the signal handler for SIGINT (i.e. ctrl+C from the terminal)
    struct sigaction sa;
    sa.sa_handler = vpr_signal_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;                  //Make sure the flags are cleared
    sigaction(SIGINT, &sa, nullptr);  //Keyboard interrupt (1 pauses, 2 quits)
    sigaction(SIGHUP, &sa, nullptr);  //Hangup (attempts to checkpoint)
    sigaction(SIGTERM, &sa, nullptr); //Terminate (attempts to checkpoint, then exit)
}

void vpr_signal_handler(int signal) {
    if (signal == SIGINT) {
        if (g_vpr_ctx.forced_pause()) {
            uncleared_sigint_count++; //Previous SIGINT uncleared
        } else {
            uncleared_sigint_count.store(1); //Only this SIGINT outstanding
        }

        if (uncleared_sigint_count == 1) {
            VTR_LOG("Recieved SIGINT: try again to really exit...\n");
        } else if (uncleared_sigint_count == 2) {
            VTR_LOG("Recieved two uncleared SIGINTs: Attempting to checkpoint and exit...\n");
            checkpoint();
            std::quick_exit(INTERRUPTED_EXIT_CODE);
        } else if (uncleared_sigint_count == 3) {
            //Really exit (e.g. SIGINT while checkpointing)
            VTR_LOG("Recieved three uncleared SIGINTs: Exiting...\n");
            std::quick_exit(INTERRUPTED_EXIT_CODE);
        }
    } else if (signal == SIGHUP) {
        VTR_LOG("Recieved SIGHUP: Attempting to checkpoint...\n");
        checkpoint();
    } else if (signal == SIGTERM) {
        VTR_LOG("Recieved SIGTERM: Attempting to checkpoint then exit...\n");
        checkpoint();
        std::quick_exit(INTERRUPTED_EXIT_CODE);
    }
}

#else
//No signal support all operations are no-ops

void vpr_install_signal_handler() {
    //Do nothing
}

void vpr_signal_handler(int /*signal*/) {
    //Do nothing
}

#endif

void checkpoint() {
    //Dump the current placement and routing state
    vtr::ScopedStartFinishTimer timer("Checkpointing");

    std::string placer_checkpoint_file = "placer_checkpoint.place";
    VTR_LOG("Attempting to checkpoint current placement to file: %s\n", placer_checkpoint_file.c_str());
    print_place(nullptr, nullptr, placer_checkpoint_file.c_str());

    std::string router_checkpoint_file = "router_checkpoint.route";
    VTR_LOG("Attempting to checkpoint current routing to file: %s\n", router_checkpoint_file.c_str());
    print_route(nullptr, router_checkpoint_file.c_str());
}
