/*
 * kmp_io.cpp -- RTL IO
 */

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef __ABSOFT_WIN
#include <sys/types.h>
#endif

#include "kmp.h" // KMP_GTID_DNE, __kmp_debug_buf, etc
#include "kmp_io.h"
#include "kmp_lock.h"
#include "kmp_os.h"
#include "kmp_str.h"

#if KMP_OS_WINDOWS
#if KMP_MSVC_COMPAT
#pragma warning(push)
#pragma warning(disable : 271 310)
#endif
#include <windows.h>
#if KMP_MSVC_COMPAT
#pragma warning(pop)
#endif
#endif

/* ------------------------------------------------------------------------ */

kmp_bootstrap_lock_t __kmp_stdio_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(
    __kmp_stdio_lock); /* Control stdio functions */
kmp_bootstrap_lock_t __kmp_console_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(
    __kmp_console_lock); /* Control console initialization */

#if KMP_OS_WINDOWS

static HANDLE __kmp_stdout = NULL;
static HANDLE __kmp_stderr = NULL;
static int __kmp_console_exists = FALSE;
static kmp_str_buf_t __kmp_console_buf;

static int is_console(void) {
  char buffer[128];
  DWORD rc = 0;
  DWORD err = 0;
  // Try to get console title.
  SetLastError(0);
  // GetConsoleTitle does not reset last error in case of success or short
  // buffer, so we need to clear it explicitly.
  rc = GetConsoleTitle(buffer, sizeof(buffer));
  if (rc == 0) {
    // rc == 0 means getting console title failed. Let us find out why.
    err = GetLastError();
    // err == 0 means buffer too short (we suppose console exists).
    // In Window applications we usually have err == 6 (invalid handle).
  }
  return rc > 0 || err == 0;
}

void __kmp_close_console(void) {
  /* wait until user presses return before closing window */
  /* TODO only close if a window was opened */
  if (__kmp_console_exists) {
    __kmp_stdout = NULL;
    __kmp_stderr = NULL;
    __kmp_str_buf_free(&__kmp_console_buf);
    __kmp_console_exists = FALSE;
  }
}

/* For windows, call this before stdout, stderr, or stdin are used.
   It opens a console window and starts processing */
static void __kmp_redirect_output(void) {
  __kmp_acquire_bootstrap_lock(&__kmp_console_lock);

  if (!__kmp_console_exists) {
    HANDLE ho;
    HANDLE he;

    __kmp_str_buf_init(&__kmp_console_buf);

    AllocConsole();
    // We do not check the result of AllocConsole because
    //  1. the call is harmless
    //  2. it is not clear how to communicate failue
    //  3. we will detect failure later when we get handle(s)

    ho = GetStdHandle(STD_OUTPUT_HANDLE);
    if (ho == INVALID_HANDLE_VALUE || ho == NULL) {

      DWORD err = GetLastError();
      // TODO: output error somehow (maybe message box)
      (void)err;
      __kmp_stdout = NULL;

    } else {

      __kmp_stdout = ho; // temporary code, need new global for ho
    }
    he = GetStdHandle(STD_ERROR_HANDLE);
    if (he == INVALID_HANDLE_VALUE || he == NULL) {

      DWORD err = GetLastError();
      // TODO: output error somehow (maybe message box)
      (void)err;
      __kmp_stderr = NULL;

    } else {

      __kmp_stderr = he; // temporary code, need new global
    }
    __kmp_console_exists = TRUE;
  }
  __kmp_release_bootstrap_lock(&__kmp_console_lock);
}

#else
#define __kmp_stderr (stderr)
#define __kmp_stdout (stdout)
#endif /* KMP_OS_WINDOWS */

void __kmp_vprintf(enum kmp_io out_stream, char const *format, va_list ap) {
#if KMP_OS_WINDOWS
  if (!__kmp_console_exists) {
    __kmp_redirect_output();
  }
  if (!__kmp_stderr && out_stream == kmp_err) {
    return;
  }
  if (!__kmp_stdout && out_stream == kmp_out) {
    return;
  }
#endif /* KMP_OS_WINDOWS */
  auto stream = ((out_stream == kmp_out) ? __kmp_stdout : __kmp_stderr);

  if (__kmp_debug_buf && __kmp_debug_buffer != NULL) {

    int dc = __kmp_debug_count++ % __kmp_debug_buf_lines;
    char *db = &__kmp_debug_buffer[dc * __kmp_debug_buf_chars];
    int chars = 0;

#ifdef KMP_DEBUG_PIDS
    chars = KMP_SNPRINTF(db, __kmp_debug_buf_chars, "pid=%d: ",
                         (kmp_int32)getpid());
#endif
    chars += KMP_VSNPRINTF(db, __kmp_debug_buf_chars, format, ap);

    if (chars + 1 > __kmp_debug_buf_chars) {
      if (chars + 1 > __kmp_debug_buf_warn_chars) {
#if KMP_OS_WINDOWS
        DWORD count;
        __kmp_str_buf_print(&__kmp_console_buf, "OMP warning: Debugging buffer "
                                                "overflow; increase "
                                                "KMP_DEBUG_BUF_CHARS to %d\n",
                            chars + 1);
        WriteFile(stream, __kmp_console_buf.str, __kmp_console_buf.used, &count,
                  NULL);
        __kmp_str_buf_clear(&__kmp_console_buf);
#else
        fprintf(stream, "OMP warning: Debugging buffer overflow; "
                        "increase KMP_DEBUG_BUF_CHARS to %d\n",
                chars + 1);
        fflush(stream);
#endif
        __kmp_debug_buf_warn_chars = chars + 1;
      }
      /* terminate string if overflow occurred */
      db[__kmp_debug_buf_chars - 2] = '\n';
      db[__kmp_debug_buf_chars - 1] = '\0';
    }
  } else {
#if KMP_OS_WINDOWS
    DWORD count;
#ifdef KMP_DEBUG_PIDS
    __kmp_str_buf_print(&__kmp_console_buf, "pid=%d: ", (kmp_int32)getpid());
#endif
    __kmp_str_buf_vprint(&__kmp_console_buf, format, ap);
    WriteFile(stream, __kmp_console_buf.str, __kmp_console_buf.used, &count,
              NULL);
    __kmp_str_buf_clear(&__kmp_console_buf);
#else
#ifdef KMP_DEBUG_PIDS
    fprintf(stream, "pid=%d: ", (kmp_int32)getpid());
#endif
    vfprintf(stream, format, ap);
    fflush(stream);
#endif
  }
}

void __kmp_printf(char const *format, ...) {
  va_list ap;
  va_start(ap, format);

  __kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);
  __kmp_vprintf(kmp_err, format, ap);
  __kmp_release_bootstrap_lock(&__kmp_stdio_lock);

  va_end(ap);
}

void __kmp_printf_no_lock(char const *format, ...) {
  va_list ap;
  va_start(ap, format);

  __kmp_vprintf(kmp_err, format, ap);

  va_end(ap);
}

void __kmp_fprintf(enum kmp_io stream, char const *format, ...) {
  va_list ap;
  va_start(ap, format);

  __kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);
  __kmp_vprintf(stream, format, ap);
  __kmp_release_bootstrap_lock(&__kmp_stdio_lock);

  va_end(ap);
}
