/*
 * 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);

  (void)is_console;
  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);
}
