/* Host support routines for MinGW, for GDB, the GNU debugger.

   Copyright (C) 2006-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "main.h"
#include "serial.h"
#include "gdbsupport/event-loop.h"
#include "gdbsupport/gdb_select.h"
#include "inferior.h"
#include "cli/cli-style.h"
#include "command.h"
#include "cli/cli-cmds.h"

#include <windows.h>
#include <signal.h>

/* Return an absolute file name of the running GDB, if possible, or
   ARGV0 if not.  The return value is in malloc'ed storage.  */

char *
windows_get_absolute_argv0 (const char *argv0)
{
  char full_name[PATH_MAX];

  if (GetModuleFileName (NULL, full_name, PATH_MAX))
    return xstrdup (full_name);
  return xstrdup (argv0);
}

/* Wrapper for select.  On Windows systems, where the select interface
   only works for sockets, this uses the GDB serial abstraction to
   handle sockets, consoles, pipes, and serial ports.

   The arguments to this function are the same as the traditional
   arguments to select on POSIX platforms.  */

int
gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
	    struct timeval *timeout)
{
  static HANDLE never_handle;
  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
  HANDLE h;
  DWORD event;
  DWORD num_handles;
  /* SCBS contains serial control objects corresponding to file
     descriptors in READFDS and WRITEFDS.  */
  struct serial *scbs[MAXIMUM_WAIT_OBJECTS];
  /* The number of valid entries in SCBS.  */
  size_t num_scbs;
  int fd;
  int num_ready;
  size_t indx;

  if (n == 0)
    {
      /* The MS API says that the first argument to
	 WaitForMultipleObjects cannot be zero.  That's why we just
	 use a regular Sleep here.  */
      if (timeout != NULL)
	Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000);

      return 0;
    }

  num_ready = 0;
  num_handles = 0;
  num_scbs = 0;
  for (fd = 0; fd < n; ++fd)
    {
      HANDLE read = NULL, except = NULL;
      struct serial *scb;

      /* There is no support yet for WRITEFDS.  At present, this isn't
	 used by GDB -- but we do not want to silently ignore WRITEFDS
	 if something starts using it.  */
      gdb_assert (!writefds || !FD_ISSET (fd, writefds));

      if ((!readfds || !FD_ISSET (fd, readfds))
	  && (!exceptfds || !FD_ISSET (fd, exceptfds)))
	continue;

      scb = serial_for_fd (fd);
      if (scb)
	{
	  serial_wait_handle (scb, &read, &except);
	  scbs[num_scbs++] = scb;
	}

      if (read == NULL)
	read = (HANDLE) _get_osfhandle (fd);
      if (except == NULL)
	{
	  if (!never_handle)
	    never_handle = CreateEvent (0, FALSE, FALSE, 0);

	  except = never_handle;
	}

      if (readfds && FD_ISSET (fd, readfds))
	{
	  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
	  handles[num_handles++] = read;
	}

      if (exceptfds && FD_ISSET (fd, exceptfds))
	{
	  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
	  handles[num_handles++] = except;
	}
    }

  gdb_assert (num_handles <= MAXIMUM_WAIT_OBJECTS);

  event = WaitForMultipleObjects (num_handles,
				  handles,
				  FALSE,
				  timeout
				  ? (timeout->tv_sec * 1000
				     + timeout->tv_usec / 1000)
				  : INFINITE);
  /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the
     HANDLES included an abandoned mutex.  Since GDB doesn't use
     mutexes, that should never occur.  */
  gdb_assert (!(WAIT_ABANDONED_0 <= event
		&& event < WAIT_ABANDONED_0 + num_handles));
  /* We no longer need the helper threads to check for activity.  */
  for (indx = 0; indx < num_scbs; ++indx)
    serial_done_wait_handle (scbs[indx]);
  if (event == WAIT_FAILED)
    return -1;
  if (event == WAIT_TIMEOUT)
    return 0;
  /* Run through the READFDS, clearing bits corresponding to descriptors
     for which input is unavailable.  */
  h = handles[event - WAIT_OBJECT_0];
  for (fd = 0, indx = 0; fd < n; ++fd)
    {
      HANDLE fd_h;

      if ((!readfds || !FD_ISSET (fd, readfds))
	  && (!exceptfds || !FD_ISSET (fd, exceptfds)))
	continue;

      if (readfds && FD_ISSET (fd, readfds))
	{
	  fd_h = handles[indx++];
	  /* This handle might be ready, even though it wasn't the handle
	     returned by WaitForMultipleObjects.  */
	  if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
	    FD_CLR (fd, readfds);
	  else
	    num_ready++;
	}

      if (exceptfds && FD_ISSET (fd, exceptfds))
	{
	  fd_h = handles[indx++];
	  /* This handle might be ready, even though it wasn't the handle
	     returned by WaitForMultipleObjects.  */
	  if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
	    FD_CLR (fd, exceptfds);
	  else
	    num_ready++;
	}
    }

  return num_ready;
}

/* Map COLOR's RGB triplet, with 8 bits per component, into 16 Windows
   console colors, where each component has just 1 bit, plus a single
   intensity bit which affects all 3 components.  */
static int
rgb_to_16colors (const ui_file_style::color &color)
{
  uint8_t rgb[3];
  color.get_rgb (rgb);

  int retval = 0;
  for (int i = 0; i < 3; i++)
    {
      /* Subdivide 256 possible values of each RGB component into 3
	 regions: no color, normal color, bright color.  256 / 3 = 85,
	 but ui-style.c follows xterm and uses 92 for R and G
	 components of the bright-blue color, so we bias the divisor a
	 bit to have the bright colors between 9 and 15 identical to
	 what ui-style.c expects.  */
      int bits = rgb[i] / 93;
      retval |= ((bits > 0) << (2 - i)) | ((bits > 1) << 3);
    }

  return retval;
}

/* Zero if not yet initialized, 1 if stdout is a console device, else -1.  */
static int mingw_console_initialized;

/* Handle to stdout . */
static HANDLE hstdout = INVALID_HANDLE_VALUE;

/* Text attribute to use for normal text (the "none" pseudo-color).  */
static SHORT norm_attr;

/* Initialize settings related to the console.  */

void
windows_initialize_console ()
{
  hstdout = (HANDLE)_get_osfhandle (fileno (stdout));
  DWORD cmode;
  CONSOLE_SCREEN_BUFFER_INFO csbi;

  if (hstdout != INVALID_HANDLE_VALUE
      && GetConsoleMode (hstdout, &cmode) != 0
      && GetConsoleScreenBufferInfo (hstdout, &csbi))
    {
      norm_attr = csbi.wAttributes;
      mingw_console_initialized = 1;
    }
  else if (hstdout != INVALID_HANDLE_VALUE)
    mingw_console_initialized = -1; /* valid, but not a console device */

  if (mingw_console_initialized > 0)
    no_emojis ();
}

/* The most recently applied style.  */
static ui_file_style last_style;

/* Alternative for the libc 'fputs' which handles embedded SGR
   sequences in support of styling.  */

int
gdb_console_fputs (const char *linebuf, FILE *fstream)
{
  /* If our stdout is not a console device, let the default 'fputs'
     handle the task. */
  if (mingw_console_initialized <= 0)
    return 0;

  /* Mapping between 8 ANSI colors and Windows console attributes.  */
  static int fg_color[] = {
    0,					/* black */
    FOREGROUND_RED,			/* red */
    FOREGROUND_GREEN,			/* green */
    FOREGROUND_GREEN | FOREGROUND_RED,	/* yellow */
    FOREGROUND_BLUE,			/* blue */
    FOREGROUND_BLUE | FOREGROUND_RED,	/* magenta */
    FOREGROUND_BLUE | FOREGROUND_GREEN, /* cyan */
    FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE /* gray */
  };
  static int bg_color[] = {
    0,					/* black */
    BACKGROUND_RED,			/* red */
    BACKGROUND_GREEN,			/* green */
    BACKGROUND_GREEN | BACKGROUND_RED,	/* yellow */
    BACKGROUND_BLUE,			/* blue */
    BACKGROUND_BLUE | BACKGROUND_RED,	/* magenta */
    BACKGROUND_BLUE | BACKGROUND_GREEN, /* cyan */
    BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE /* gray */
  };

  ui_file_style style = last_style;
  unsigned char c;
  size_t n_read;

  for ( ; (c = *linebuf) != 0; linebuf += n_read)
    {
      if (c == '\033')
	{
	  fflush (fstream);
	  bool parsed = style.parse (linebuf, &n_read);
	  if (n_read <= 0)	/* should never happen */
	    n_read = 1;
	  if (!parsed)
	    {
	      /* This means we silently swallow SGR sequences we
		 cannot parse.  */
	      continue;
	    }
	  /* Colors.  */
	  const ui_file_style::color &fg = style.get_foreground ();
	  const ui_file_style::color &bg = style.get_background ();
	  int fgcolor, bgcolor, bright, inverse;
	  if (fg.is_none ())
	    fgcolor = norm_attr & 15;
	  else if (fg.is_basic ())
	    fgcolor = fg_color[fg.get_value () & 15];
	  else
	    fgcolor = rgb_to_16colors (fg);
	  if (bg.is_none ())
	    bgcolor = norm_attr & (15 << 4);
	  else if (bg.is_basic ())
	    bgcolor = bg_color[bg.get_value () & 15];
	  else
	    bgcolor = rgb_to_16colors (bg) << 4;

	  /* Intensity.  */
	  switch (style.get_intensity ())
	    {
	    case ui_file_style::NORMAL:
	    case ui_file_style::DIM:
	      bright = 0;
	      break;
	    case ui_file_style::BOLD:
	      bright = 1;
	      break;
	    default:
	      gdb_assert_not_reached ("invalid intensity");
	    }

	  /* Inverse video.  */
	  if (style.is_reverse ())
	    inverse = 1;
	  else
	    inverse = 0;

	  /* Construct the attribute.  */
	  if (inverse)
	    {
	      int t = fgcolor;
	      fgcolor = (bgcolor >> 4);
	      bgcolor = (t << 4);
	    }
	  if (bright)
	    fgcolor |= FOREGROUND_INTENSITY;

	  SHORT attr = (bgcolor & (15 << 4)) | (fgcolor & 15);

	  /* Apply the attribute.  */
	  SetConsoleTextAttribute (hstdout, attr);
	}
      else
	{
	  /* When we are about to write newline, we need to clear to
	     EOL with the normal attribute, to avoid spilling the
	     colors to the next screen line.  We assume here that no
	     non-default attribute extends beyond the newline.  */
	  if (c == '\n')
	    {
	      DWORD nchars;
	      COORD start_pos;
	      DWORD written;
	      CONSOLE_SCREEN_BUFFER_INFO csbi;

	      fflush (fstream);
	      GetConsoleScreenBufferInfo (hstdout, &csbi);

	      if (csbi.wAttributes != norm_attr)
		{
		  start_pos = csbi.dwCursorPosition;
		  nchars = csbi.dwSize.X - start_pos.X;

		  FillConsoleOutputAttribute (hstdout, norm_attr, nchars,
					      start_pos, &written);
		  FillConsoleOutputCharacter (hstdout, ' ', nchars,
					      start_pos, &written);
		}
	    }
	  fputc (c, fstream);
	  n_read = 1;
	}
    }

  last_style = style;
  return 1;
}

/* See inferior.h.  */

tribool
sharing_input_terminal (int pid)
{
  std::vector<DWORD> results (10);
  DWORD len = 0;
  while (true)
    {
      len = GetConsoleProcessList (results.data (), results.size ());
      /* Note that LEN == 0 is a failure, but we can treat it the same
	 as a "no".  */
      if (len <= results.size ())
	break;

      results.resize (len);
    }
  /* In case the vector was too big.  */
  results.resize (len);
  if (std::find (results.begin (), results.end (), pid) != results.end ())
    {
      /* The pid is in the list sharing the console, so don't
	 interrupt the inferior -- it will get the signal itself.  */
      return TRIBOOL_TRUE;
    }

  return TRIBOOL_FALSE;
}

/* Current C-c handler.  */
static c_c_handler_ftype *current_handler;

/* The Windows callback that forwards requests to the C-c handler.  */
static BOOL WINAPI
ctrl_c_handler (DWORD event_type)
{
  if (event_type == CTRL_BREAK_EVENT || event_type == CTRL_C_EVENT)
    {
      if (current_handler != SIG_IGN)
	current_handler (SIGINT);
    }
  else
    return FALSE;
  return TRUE;
}

/* See inferior.h.  */

c_c_handler_ftype *
install_sigint_handler (c_c_handler_ftype *fn)
{
  /* We want to make sure the gdb handler always comes first, so that
     gdb gets to handle the C-c.  This is why the handler is always
     removed and reinstalled here.  Note that trying to remove the
     function without installing it first will cause a crash.  */
  static bool installed = false;
  if (installed)
    SetConsoleCtrlHandler (ctrl_c_handler, FALSE);
  SetConsoleCtrlHandler (ctrl_c_handler, TRUE);
  installed = true;

  c_c_handler_ftype *result = current_handler;
  current_handler = fn;
  return result;
}

/* Set stdout and stderr handles to translation mode MODE.  */

static void
set_console_translation_mode (int mode)
{
  setmode (fileno (stdout), mode);
  setmode (fileno (stderr), mode);
}

/* Arg in "maint set console-translation-mode <arg>.  */

static std::string maint_console_translation_mode;

/* Current value of "maint set/show console-translation-mode".  */

static std::string console_translation_mode = "unknown";

/* Sets the console translation mode.  */

static void
set_maint_console_translation_mode (const char *args, int from_tty,
				    struct cmd_list_element *c)
{
  if (maint_console_translation_mode == "binary")
    set_console_translation_mode (O_BINARY);
  else if (maint_console_translation_mode == "text")
    set_console_translation_mode (O_TEXT);
  else
    error (_("Invalid console translation mode: %s"),
	   maint_console_translation_mode.c_str ());

  console_translation_mode = maint_console_translation_mode;
}

/* Shows the console translation mode.  */

static void
show_maint_console_translation_mode (struct ui_file *file, int from_tty,
				     struct cmd_list_element *c,
				     const char *value)
{
  gdb_printf (file, _("Console translation mode is %s.\n"),
	      console_translation_mode.c_str ());
}

INIT_GDB_FILE (mingw_hdep)
{
  add_setshow_string_cmd ("console-translation-mode",
			  class_maintenance,
			  &maint_console_translation_mode, _("\
Set the translation mode of stdout/stderr."), _("\
Show the translation mode of stdout/stderr."), _("\
Use \"binary\", or \"text\""),
			   set_maint_console_translation_mode,
			   show_maint_console_translation_mode,
			   &maintenance_set_cmdlist,
			   &maintenance_show_cmdlist);
}
