/* Provide prerequisite shuffle support.
Copyright (C) 2022-2025 Free Software Foundation, Inc.
This file is part of GNU Make.

GNU Make 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.

GNU Make 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 <https://www.gnu.org/licenses/>.  */

#include "makeint.h"

#include "shuffle.h"

#include "filedef.h"
#include "dep.h"

/* Supported shuffle modes.  */
static void random_shuffle_array (void ** a, size_t len);
static void reverse_shuffle_array (void ** a, size_t len);
static void identity_shuffle_array (void ** a, size_t len);

/* The way goals and rules are shuffled during update.  */
enum shuffle_mode
  {
    /* No shuffle data is populated or used.  */
    sm_none,
    /* Random within dependency list.  */
    sm_random,
    /* Inverse order.  */
    sm_reverse,
    /* identity order. Differs from SM_NONE by explicitly populating
       the traversal order.  */
    sm_identity,
  };

/* Shuffle configuration.  */
static struct
  {
    enum shuffle_mode mode;
    unsigned int seed;
    void (*shuffler) (void **a, size_t len);
    char strval[INTSTR_LENGTH + 1];
  } config = { sm_none, 0, NULL, "" };

/* Return string value of --shuffle= option passed.
   If none was passed or --shuffle=none was used function
   returns NULL.  */
const char *
shuffle_get_mode ()
{
  return config.strval[0] == '\0' ? NULL : config.strval;
}

void
shuffle_set_mode (const char *cmdarg)
{
  /* Parse supported '--shuffle' mode.  */
  if (strcasecmp (cmdarg, "reverse") == 0)
    {
      config.mode = sm_reverse;
      config.shuffler = reverse_shuffle_array;
      strcpy (config.strval, "reverse");
    }
  else if (strcasecmp (cmdarg, "identity") == 0)
    {
      config.mode = sm_identity;
      config.shuffler = identity_shuffle_array;
      strcpy (config.strval, "identity");
    }
  else if (strcasecmp (cmdarg, "none") == 0)
    {
      config.mode = sm_none;
      config.shuffler = NULL;
      config.strval[0] = '\0';
    }
  else
    {
      if (strcasecmp (cmdarg, "random") == 0)
        config.seed = make_rand ();
      else
        {
          /* Assume explicit seed.  */
          const char *err;
          config.seed = make_toui (cmdarg, &err);
          if (err)
            OSS (fatal, NILF, _("invalid shuffle mode: %s: '%s'"), err, cmdarg);
        }

      config.mode = sm_random;
      config.shuffler = random_shuffle_array;
      sprintf (config.strval, "%u", config.seed);
    }
}

/* Shuffle array elements using RAND().  */
static void
random_shuffle_array (void **a, size_t len)
{
  size_t i;

  if (len <= 1)
    return;

  for (i = len - 1; i >= 1; i--)
    {
      void *t;

      /* Pick random element and swap. */
      unsigned int j = make_rand () % (i + 1);
      if (i == j)
        continue;

      /* Swap. */
      t = a[i];
      a[i] = a[j];
      a[j] = t;
    }
}

/* Shuffle array elements using reverse order.  */
static void
reverse_shuffle_array (void **a, size_t len)
{
  size_t i;
  for (i = 0; i < len / 2; i++)
    {
      void *t;

      /* Pick mirror and swap. */
      size_t j = len - 1 - i;

      /* Swap. */
      t = a[i];
      a[i] = a[j];
      a[j] = t;
    }
}

/* Shuffle array elements using identity order.  */
static void
identity_shuffle_array (void **a UNUSED, size_t len UNUSED)
{
  /* No-op!  */
}

/* Shuffle list of dependencies by populating '->shuf'
   field in each 'struct dep'.  */
static void
shuffle_deps (struct dep *deps)
{
  size_t ndeps = 0;
  struct dep *dep;
  void **da;
  void **dp;

  for (dep = deps; dep; dep = dep->next)
    {
      /* Do not reshuffle prerequisites if any .WAIT is present.  */
      if (dep->wait_here)
        return;

      ndeps++;
    }

  if (ndeps == 0)
    return;

  /* Allocate array of all deps, store, shuffle, write back.  */
  da = xmalloc (sizeof (struct dep *) * ndeps);

  /* Store locally.  */
  for (dep = deps, dp = da; dep; dep = dep->next, dp++)
    *dp = dep;

  /* Shuffle.  */
  config.shuffler (da, ndeps);

  /* Write back.  */
  for (dep = deps, dp = da; dep; dep = dep->next, dp++)
    dep->shuf = *dp;

  free (da);
}

/* Shuffle 'deps' of each 'file' recursively.  */
static void
shuffle_file_deps_recursive (struct file *f)
{
  struct dep *dep;

  /* Implicit rules do not always provide any depends.  */
  if (!f)
    return;

  /* Avoid repeated shuffles and loops.  */
  if (f->was_shuffled)
    return;
  f->was_shuffled = 1;

  shuffle_deps (f->deps);

  /* Shuffle dependencies. */
  for (dep = f->deps; dep; dep = dep->next)
    shuffle_file_deps_recursive (dep->file);
}

/* Shuffle goal dependencies first, then shuffle dependency list
   of each file reachable from goaldep recursively.  Used by
   --shuffle flag to introduce artificial non-determinism in build
   order.  .*/

void
shuffle_deps_recursive (struct dep *deps)
{
  struct dep *dep;

  /* Exit early if shuffling was not requested.  */
  if (config.mode == sm_none)
    return;

  /* Do not reshuffle prerequisites if .NOTPARALLEL was specified.  */
  if (not_parallel)
    return;

  /* Set specific seed at the top level of recursion.  */
  if (config.mode == sm_random)
    make_seed (config.seed);

  shuffle_deps (deps);

  /* Shuffle dependencies. */
  for (dep = deps; dep; dep = dep->next)
    shuffle_file_deps_recursive (dep->file);
}
