#include "colors.h"
#include "cover.h"
#include "error.h"

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

static void (*kissat_abort_function) (void);

void
kissat_call_function_instead_of_abort (void (*f) (void))
{
  kissat_abort_function = f;
}

// *INDENT-OFF*

void
kissat_abort (void)
{
  if (kissat_abort_function)
    { FLUSH_COVERAGE (); kissat_abort_function (); } // Keep all in this line.
  else
    { FLUSH_COVERAGE (); abort (); }                 // Keep all in this line.
}

// *INDENT-ON*

static void
typed_error_message_start (const char *type)
{
  fflush (stdout);
  TERMINAL (stderr, 2);
  COLOR (BOLD);
  fputs ("kissat: ", stderr);
  COLOR (RED);
  fputs (type, stderr);
  fputs (": ", stderr);
  COLOR (NORMAL);
}

void
kissat_fatal_message_start (void)
{
  typed_error_message_start ("fatal error");
}

static void
vprint_error (const char *type, const char *fmt, va_list * ap)
{
  typed_error_message_start (type);
  vfprintf (stderr, fmt, *ap);
  fputc ('\n', stderr);
  fflush (stderr);
}

void
kissat_error (const char *fmt, ...)
{
  va_list ap;
  va_start (ap, fmt);
  vprint_error ("error", fmt, &ap);
  va_end (ap);
}

void
kissat_fatal (const char *fmt, ...)
{
  va_list ap;
  va_start (ap, fmt);
  vprint_error ("fatal error", fmt, &ap);
  va_end (ap);
  kissat_abort ();
}