/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2009  Free Software Foundation, Inc.
 *
 *  GRUB 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.
 *
 *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/normal.h>
#include <grub/misc.h>
#include <grub/term.h>
#include <grub/err.h>
#include <grub/types.h>
#include <grub/mm.h>
#include <grub/partition.h>
#include <grub/disk.h>
#include <grub/file.h>
#include <grub/env.h>
#include <grub/i18n.h>
#include <grub/charset.h>

static grub_uint32_t *kill_buf;

static int hist_size;
static grub_uint32_t **hist_lines = 0;
static int hist_pos = 0;
static int hist_end = 0;
static int hist_used = 0;

grub_err_t
grub_set_history (int newsize)
{
  grub_uint32_t **old_hist_lines = hist_lines;
  hist_lines = grub_malloc (sizeof (grub_uint32_t *) * newsize);

  /* Copy the old lines into the new buffer.  */
  if (old_hist_lines)
    {
      /* Remove the lines that don't fit in the new buffer.  */
      if (newsize < hist_used)
	{
	  grub_size_t i;
	  grub_size_t delsize = hist_used - newsize;
	  hist_used = newsize;

	  for (i = 1; i < delsize + 1; i++)
	    {
	      grub_ssize_t pos = hist_end - i;
	      if (pos < 0)
		pos += hist_size;
	      grub_free (old_hist_lines[pos]);
	    }

	  hist_end -= delsize;
	  if (hist_end < 0)
	    hist_end += hist_size;
	}

      if (hist_pos < hist_end)
	grub_memmove (hist_lines, old_hist_lines + hist_pos,
		      (hist_end - hist_pos) * sizeof (grub_uint32_t *));
      else if (hist_used)
	{
	  /* Copy the older part.  */
	  grub_memmove (hist_lines, old_hist_lines + hist_pos,
 			(hist_size - hist_pos) * sizeof (grub_uint32_t *));

	  /* Copy the newer part. */
	  grub_memmove (hist_lines + hist_size - hist_pos, old_hist_lines,
			hist_end * sizeof (grub_uint32_t *));
	}
    }

  grub_free (old_hist_lines);

  hist_size = newsize;
  hist_pos = 0;
  hist_end = hist_used;
  return 0;
}

/* Get the entry POS from the history where `0' is the newest
   entry.  */
static grub_uint32_t *
grub_history_get (unsigned pos)
{
  pos = (hist_pos + pos) % hist_size;
  return hist_lines[pos];
}

static grub_size_t
strlen_ucs4 (const grub_uint32_t *s)
{
  const grub_uint32_t *p = s;

  while (*p)
    p++;

  return p - s;
}

/* Replace the history entry on position POS with the string S.  */
static void
grub_history_set (int pos, grub_uint32_t *s, grub_size_t len)
{
  grub_free (hist_lines[pos]);
  hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_uint32_t));
  if (!hist_lines[pos])
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
      return ;
    }
  grub_memcpy (hist_lines[pos], s, len * sizeof (grub_uint32_t));
  hist_lines[pos][len] = 0;
}

/* Insert a new history line S on the top of the history.  */
static void
grub_history_add (grub_uint32_t *s, grub_size_t len)
{
  /* Remove the oldest entry in the history to make room for a new
     entry.  */
  if (hist_used + 1 > hist_size)
    {
      hist_end--;
      if (hist_end < 0)
	hist_end = hist_size + hist_end;

      grub_free (hist_lines[hist_end]);
    }
  else
    hist_used++;

  /* Move to the next position.  */
  hist_pos--;
  if (hist_pos < 0)
    hist_pos = hist_size + hist_pos;

  /* Insert into history.  */
  hist_lines[hist_pos] = NULL;
  grub_history_set (hist_pos, s, len);
}

/* Replace the history entry on position POS with the string S.  */
static void
grub_history_replace (unsigned pos, grub_uint32_t *s, grub_size_t len)
{
  grub_history_set ((hist_pos + pos) % hist_size, s, len);
}

/* A completion hook to print items.  */
static void
print_completion (const char *item, grub_completion_type_t type, int count)
{
  if (count == 0)
    {
      /* If this is the first time, print a label.  */
      
      grub_puts ("");
      switch (type)
	{
	case GRUB_COMPLETION_TYPE_COMMAND:
	  grub_puts_ (N_("Possible commands are:"));
	  break;
	case GRUB_COMPLETION_TYPE_DEVICE:
	  grub_puts_ (N_("Possible devices are:"));
	  break;
	case GRUB_COMPLETION_TYPE_FILE:
	  grub_puts_ (N_("Possible files are:"));
	  break;
	case GRUB_COMPLETION_TYPE_PARTITION:
	  grub_puts_ (N_("Possible partitions are:"));
	  break;
	case GRUB_COMPLETION_TYPE_ARGUMENT:
	  grub_puts_ (N_("Possible arguments are:"));
	  break;
	default:
	  /* TRANSLATORS: this message is used if none of above matches.
	     This shouldn't happen but please use the general term for
	     "thing" or "object".  */
	  grub_puts_ (N_("Possible things are:"));
	  break;
	}
      grub_puts ("");
    }

  if (type == GRUB_COMPLETION_TYPE_PARTITION)
    {
      grub_normal_print_device_info (item);
      grub_errno = GRUB_ERR_NONE;
    }
  else
    grub_printf (" %s", item);
}

struct cmdline_term
{
  struct grub_term_coordinate pos;
  unsigned ystart, width, height;
  unsigned prompt_len;
  struct grub_term_output *term;
};

static inline void
cl_set_pos (struct cmdline_term *cl_term, grub_size_t lpos)
{
  cl_term->pos.x = (cl_term->prompt_len + lpos) % cl_term->width;
  cl_term->pos.y = cl_term->ystart
    + (cl_term->prompt_len + lpos) / cl_term->width;
  grub_term_gotoxy (cl_term->term, cl_term->pos);
}

static void
cl_set_pos_all (struct cmdline_term *cl_terms, unsigned nterms,
		grub_size_t lpos)
{
  unsigned i;
  for (i = 0; i < nterms; i++)
    cl_set_pos (&cl_terms[i], lpos);
}

static inline void __attribute__ ((always_inline))
cl_print (struct cmdline_term *cl_term, grub_uint32_t c,
	  grub_uint32_t *start, grub_uint32_t *end)
{
  grub_uint32_t *p;

  for (p = start; p < end; p++)
    {
      if (c)
	grub_putcode (c, cl_term->term);
      else
	grub_putcode (*p, cl_term->term);
      cl_term->pos.x++;
      if (cl_term->pos.x >= cl_term->width - 1)
	{
	  cl_term->pos.x = 0;
	  if (cl_term->pos.y >= (unsigned) (cl_term->height - 1))
	    cl_term->ystart--;
	  else
	    cl_term->pos.y++;
	  grub_putcode ('\n', cl_term->term);
	}
    }
}

static void
cl_print_all (struct cmdline_term *cl_terms, unsigned nterms,
	      grub_uint32_t c, grub_uint32_t *start, grub_uint32_t *end)
{
  unsigned i;
  for (i = 0; i < nterms; i++)
    cl_print (&cl_terms[i], c, start, end);
}

static void
init_clterm (struct cmdline_term *cl_term_cur)
{
  cl_term_cur->pos.x = cl_term_cur->prompt_len;
  cl_term_cur->pos.y = grub_term_getxy (cl_term_cur->term).y;
  cl_term_cur->ystart = cl_term_cur->pos.y;
  cl_term_cur->width = grub_term_width (cl_term_cur->term);
  cl_term_cur->height = grub_term_height (cl_term_cur->term);
}


static void
cl_delete (struct cmdline_term *cl_terms, unsigned nterms,
	   grub_uint32_t *buf,
	   grub_size_t lpos, grub_size_t *llen, unsigned len)
{
  if (lpos + len <= (*llen))
    {
      cl_set_pos_all (cl_terms, nterms, (*llen) - len);
      cl_print_all (cl_terms, nterms, ' ', buf + (*llen) - len, buf + (*llen));

      cl_set_pos_all (cl_terms, nterms, lpos);

      grub_memmove (buf + lpos, buf + lpos + len,
		    sizeof (grub_uint32_t) * ((*llen) - lpos + 1));
      (*llen) -= len;
      cl_print_all (cl_terms, nterms, 0, buf + lpos, buf + (*llen));
      cl_set_pos_all (cl_terms, nterms, lpos);
    }
}


static void
cl_insert (struct cmdline_term *cl_terms, unsigned nterms,
	   grub_size_t *lpos, grub_size_t *llen,
	   grub_size_t *max_len, grub_uint32_t **buf,
	   const grub_uint32_t *str)
{
  grub_size_t len = strlen_ucs4 (str);

  if (len + (*llen) >= (*max_len))
    {
      grub_uint32_t *nbuf;
      (*max_len) *= 2;
      nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len));
      if (nbuf)
	(*buf) = nbuf;
      else
	{
	  grub_print_error ();
	  grub_errno = GRUB_ERR_NONE;
	  (*max_len) /= 2;
	}
    }

  if (len + (*llen) < (*max_len))
    {
      grub_memmove ((*buf) + (*lpos) + len, (*buf) + (*lpos),
		    ((*llen) - (*lpos) + 1) * sizeof (grub_uint32_t));
      grub_memmove ((*buf) + (*lpos), str, len * sizeof (grub_uint32_t));

      (*llen) += len;
      cl_set_pos_all (cl_terms, nterms, (*lpos));
      cl_print_all (cl_terms, nterms, 0, *buf + (*lpos), *buf + (*llen));
      (*lpos) += len;
      cl_set_pos_all (cl_terms, nterms, (*lpos));
    }
}


/* Get a command-line. If ESC is pushed, return zero,
   otherwise return command line.  */
/* FIXME: The dumb interface is not supported yet.  */
char *
grub_cmdline_get (const char *prompt_translated)
{
  grub_size_t lpos, llen;
  grub_uint32_t *buf;
  grub_size_t max_len = 256;
  int key;
  int histpos = 0;
  struct cmdline_term *cl_terms;
  char *ret;
  unsigned nterms;

  buf = grub_malloc (max_len * sizeof (grub_uint32_t));
  if (!buf)
    return 0;

  lpos = llen = 0;
  buf[0] = '\0';

  {
    grub_term_output_t term;

    FOR_ACTIVE_TERM_OUTPUTS(term)
      if ((grub_term_getxy (term).x) != 0)
	grub_putcode ('\n', term);
  }
  grub_xputs (prompt_translated);
  grub_xputs (" ");
  grub_normal_reset_more ();

  {
    struct cmdline_term *cl_term_cur;
    struct grub_term_output *cur;
    grub_uint32_t *unicode_msg;
    grub_size_t msg_len = grub_strlen (prompt_translated) + 3;

    nterms = 0;
    FOR_ACTIVE_TERM_OUTPUTS(cur)
      nterms++;

    cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms);
    if (!cl_terms)
      {
	grub_free (buf);
	return 0;
      }
    cl_term_cur = cl_terms;

    unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t));
    if (!unicode_msg)
      {
	grub_free (buf);
	grub_free (cl_terms);
	return 0;
      }
    msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len - 1,
				 (grub_uint8_t *) prompt_translated, -1, 0);
    unicode_msg[msg_len++] = ' ';

    FOR_ACTIVE_TERM_OUTPUTS(cur)
    {
      cl_term_cur->term = cur;
      cl_term_cur->prompt_len = grub_getstringwidth (unicode_msg,
						     unicode_msg + msg_len,
						     cur);
      init_clterm (cl_term_cur);
      cl_term_cur++;
    }
    grub_free (unicode_msg);
  }

  if (hist_used == 0)
    grub_history_add (buf, llen);

  grub_refresh ();

  while ((key = grub_getkey ()) != '\n' && key != '\r')
    {
      switch (key)
	{
	case GRUB_TERM_CTRL | 'a':
	case GRUB_TERM_KEY_HOME:
	  lpos = 0;
	  cl_set_pos_all (cl_terms, nterms, lpos);
	  break;

	case GRUB_TERM_CTRL | 'b':
	case GRUB_TERM_KEY_LEFT:
	  if (lpos > 0)
	    {
	      lpos--;
	      cl_set_pos_all (cl_terms, nterms, lpos);
	    }
	  break;

	case GRUB_TERM_CTRL | 'e':
	case GRUB_TERM_KEY_END:
	  lpos = llen;
	  cl_set_pos_all (cl_terms, nterms, lpos);
	  break;

	case GRUB_TERM_CTRL | 'f':
	case GRUB_TERM_KEY_RIGHT:
	  if (lpos < llen)
	    {
	      lpos++;
	      cl_set_pos_all (cl_terms, nterms, lpos);
	    }
	  break;

	case GRUB_TERM_CTRL | 'i':
	case '\t':
	  {
	    int restore;
	    char *insertu8;
	    char *bufu8;
	    grub_uint32_t c;

	    c = buf[lpos];
	    buf[lpos] = '\0';

	    bufu8 = grub_ucs4_to_utf8_alloc (buf, lpos);
	    buf[lpos] = c;
	    if (!bufu8)
	      {
		grub_print_error ();
		grub_errno = GRUB_ERR_NONE;
		break;
	      }

	    insertu8 = grub_normal_do_completion (bufu8, &restore,
						  print_completion);
	    grub_free (bufu8);

	    grub_normal_reset_more ();

	    if (restore)
	      {
		unsigned i;

		/* Restore the prompt.  */
		grub_xputs ("\n");
		grub_xputs (prompt_translated);
		grub_xputs (" ");

		for (i = 0; i < nterms; i++)
		  init_clterm (&cl_terms[i]);

		cl_print_all (cl_terms, nterms, 0, buf, buf + llen);
	      }

	    if (insertu8)
	      {
		grub_size_t insertlen;
		grub_ssize_t t;
		grub_uint32_t *insert;

		insertlen = grub_strlen (insertu8);
		insert = grub_malloc ((insertlen + 1) * sizeof (grub_uint32_t));
		if (!insert)
		  {
		    grub_free (insertu8);
		    grub_print_error ();
		    grub_errno = GRUB_ERR_NONE;
		    break;
		  }
		t = grub_utf8_to_ucs4 (insert, insertlen,
				       (grub_uint8_t *) insertu8,
				       insertlen, 0);
		if (t > 0)
		  {
		    if (insert[t-1] == ' ' && buf[lpos] == ' ')
		      {
			insert[t-1] = 0;
			if (t != 1)
			  cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, insert);
			lpos++;
		      }
		    else
		      {
			insert[t] = 0;
			cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, insert);
		      }
		  }

		grub_free (insertu8);
		grub_free (insert);
	      }
	    cl_set_pos_all (cl_terms, nterms, lpos);
	  }
	  break;

	case GRUB_TERM_CTRL | 'k':
	  if (lpos < llen)
	    {
	      grub_free (kill_buf);

	      kill_buf = grub_malloc ((llen - lpos + 1)
				      * sizeof (grub_uint32_t));
	      if (grub_errno)
		{
		  grub_print_error ();
		  grub_errno = GRUB_ERR_NONE;
		}
	      else
		{
		  grub_memcpy (kill_buf, buf + lpos,
			       (llen - lpos + 1) * sizeof (grub_uint32_t));
		  kill_buf[llen - lpos] = 0;
		}

	      cl_delete (cl_terms, nterms,
			 buf, lpos, &llen, llen - lpos);
	    }
	  break;

	case GRUB_TERM_CTRL | 'n':
	case GRUB_TERM_KEY_DOWN:
	  {
	    grub_uint32_t *hist;

	    lpos = 0;

	    if (histpos > 0)
	      {
		grub_history_replace (histpos, buf, llen);
		histpos--;
	      }

	    cl_delete (cl_terms, nterms,
		       buf, lpos, &llen, llen);
	    hist = grub_history_get (histpos);
	    cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, hist);

	    break;
	  }

	case GRUB_TERM_KEY_UP:
	case GRUB_TERM_CTRL | 'p':
	  {
	    grub_uint32_t *hist;

	    lpos = 0;

	    if (histpos < hist_used - 1)
	      {
		grub_history_replace (histpos, buf, llen);
		histpos++;
	      }

	    cl_delete (cl_terms, nterms,
		       buf, lpos, &llen, llen);
	    hist = grub_history_get (histpos);

	    cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, hist);
	  }
	  break;

	case GRUB_TERM_CTRL | 'u':
	  if (lpos > 0)
	    {
	      grub_size_t n = lpos;

	      grub_free (kill_buf);

	      kill_buf = grub_malloc ((n + 1) * sizeof(grub_uint32_t));
	      if (grub_errno)
		{
		  grub_print_error ();
		  grub_errno = GRUB_ERR_NONE;
		}
	      if (kill_buf)
		{
		  grub_memcpy (kill_buf, buf, n * sizeof(grub_uint32_t));
		  kill_buf[n] = 0;
		}

	      lpos = 0;
	      cl_set_pos_all (cl_terms, nterms, lpos);
	      cl_delete (cl_terms, nterms,
			 buf, lpos, &llen, n);
	    }
	  break;

	case GRUB_TERM_CTRL | 'y':
	  if (kill_buf)
	    cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, kill_buf);
	  break;

	case '\e':
	  grub_free (cl_terms);
	  grub_free (buf);
	  return 0;

	case '\b':
	  if (lpos > 0)
	    {
	      lpos--;
	      cl_set_pos_all (cl_terms, nterms, lpos);
	    }
          else
            break;
	  /* fall through */

	case GRUB_TERM_CTRL | 'd':
	case GRUB_TERM_KEY_DC:
	  if (lpos < llen)
	    cl_delete (cl_terms, nterms,
		       buf, lpos, &llen, 1);
	  break;

	default:
	  if (grub_isprint (key))
	    {
	      grub_uint32_t str[2];

	      str[0] = key;
	      str[1] = '\0';
	      cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, str);
	    }
	  break;
	}

      grub_refresh ();
    }

  grub_xputs ("\n");
  grub_refresh ();

  histpos = 0;
  if (strlen_ucs4 (buf) > 0)
    {
      grub_uint32_t empty[] = { 0 };
      grub_history_replace (histpos, buf, llen);
      grub_history_add (empty, 0);
    }

  ret = grub_ucs4_to_utf8_alloc (buf, llen + 1);
  grub_free (buf);
  grub_free (cl_terms);
  return ret;
}
