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