/* Support for fixing grammar files.

   Copyright (C) 2019 Free Software Foundation, Inc.

   This file is part of Bison, the GNU Compiler Compiler.

   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 <config.h>

#include "fixits.h"

#include "system.h"

#include "error.h"
#include "get-errno.h"
#include "getargs.h"
#include "gl_array_list.h"
#include "gl_xlist.h"
#include "progname.h"
#include "quote.h"
#include "quotearg.h"
#include "vasnprintf.h"

#include "files.h"

typedef struct
{
  location location;
  char *fix;
} fixit;

gl_list_t fixits = NULL;

static fixit *
fixit_new (location const *loc, char const* fix)
{
  fixit *res = xmalloc (sizeof *res);
  res->location = *loc;
  res->fix = xstrdup (fix);
  return res;
}

static int
fixit_cmp (const  fixit *a, const fixit *b)
{
  return location_cmp (a->location, b->location);
}

static void
fixit_free (fixit *f)
{
  free (f->fix);
  free (f);
}


/* GCC and Clang follow the same pattern.
   https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Message-Formatting-Options.html
   http://clang.llvm.org/docs/UsersManual.html#cmdoption-fdiagnostics-parseable-fixits */
static void
fixit_print (fixit const *f, FILE *out)
{
  fprintf (out, "fix-it:%s:{%d:%d-%d:%d}:%s\n",
           quotearg_n_style (1, c_quoting_style, f->location.start.file),
           f->location.start.line, f->location.start.byte,
           f->location.end.line, f->location.end.byte,
           quotearg_n_style (2, c_quoting_style, f->fix));
}


void
fixits_register (location const *loc, char const* fix)
{
  if (!fixits)
    fixits = gl_list_create_empty (GL_ARRAY_LIST,
                                   /* equals */ NULL,
                                   /* hashcode */ NULL,
                                   (gl_listelement_dispose_fn) fixit_free,
                                   true);
  fixit *f = fixit_new (loc, fix);
  gl_sortedlist_add (fixits, (gl_listelement_compar_fn) fixit_cmp, f);
  if (feature_flag & feature_fixit)
    fixit_print (f, stderr);
}


bool
fixits_empty (void)
{
  return !fixits;
}


void
fixits_run (void)
{
  if (!fixits)
    return;

  /* This is not unlike what is done in location_caret.  */
  uniqstr input = ((fixit *) gl_list_get_at (fixits, 0))->location.start.file;
  /* Backup the file. */
  char buf[256];
  size_t len = sizeof (buf);
  char *backup = asnprintf (buf, &len, "%s~", input);
  if (!backup)
    xalloc_die ();
  if (rename (input, backup))
    error (EXIT_FAILURE, get_errno (),
           _("%s: cannot backup"), quotearg_colon (input));
  FILE *in = xfopen (backup, "r");
  FILE *out = xfopen (input, "w");
  size_t line = 1;
  size_t offset = 1;
  fixit const *f = NULL;
  gl_list_iterator_t iter = gl_list_iterator (fixits);
  while (gl_list_iterator_next (&iter, (const void**) &f, NULL))
    {
      /* Look for the correct line. */
      while (line < f->location.start.line)
        {
          int c = getc (in);
          if (c == EOF)
            break;
          if (c == '\n')
            {
              ++line;
              offset = 1;
            }
          putc (c, out);
        }

      /* Look for the right offset. */
      bool need_eol = false;
      while (offset < f->location.start.byte)
        {
          int c = getc (in);
          if (c == EOF)
            break;
          ++offset;
          if (c == '\n')
            /* The position we are asked for is beyond the actual
               line: pad with spaces, and remember we need a \n.  */
            need_eol = true;
          putc (need_eol ? ' ' : c, out);
        }

      /* Paste the fix instead. */
      fputs (f->fix, out);

      /* Maybe install the eol afterwards.  */
      if (need_eol)
        putc ('\n', out);

      /* Skip the bad input. */
      while (line < f->location.end.line)
        {
          int c = getc (in);
          if (c == EOF)
            break;
          if (c == '\n')
            {
              ++line;
              offset = 1;
            }
        }
      while (offset < f->location.end.byte)
        {
          int c = getc (in);
          if (c == EOF)
            break;
          ++offset;
        }

      /* If erasing the content of a full line, also remove the
         end-of-line. */
      if (f->fix[0] == 0 && f->location.start.byte == 1)
        {
          int c = getc (in);
          if (c == EOF)
            break;
          else if (c == '\n')
            {
              ++line;
              offset = 1;
            }
          else
            ungetc (c, in);
        }
    }
  /* Paste the rest of the file.  */
  {
    int c;
    while ((c = getc (in)) != EOF)
      putc (c, out);
  }

  gl_list_iterator_free (&iter);
  xfclose (out);
  xfclose (in);
  fprintf (stderr, "%s: file %s was updated (backup: %s)\n",
           program_name, quote_n (0, input), quote_n (1, backup));
  if (backup != buf)
    free (backup);
}


/* Free the registered fixits.  */
void fixits_free (void)
{
  if (fixits)
    {
      gl_list_free (fixits);
      fixits = NULL;
    }
}
