/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2010,2011  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/misc.h>
#include <grub/net/tcp.h>
#include <grub/net/ip.h>
#include <grub/net/ethernet.h>
#include <grub/net/netbuff.h>
#include <grub/net.h>
#include <grub/mm.h>
#include <grub/dl.h>
#include <grub/file.h>
#include <grub/i18n.h>

GRUB_MOD_LICENSE ("GPLv3+");

enum
  {
    HTTP_PORT = 80
  };


typedef struct http_data
{
  char *current_line;
  grub_size_t current_line_len;
  int headers_recv;
  int first_line_recv;
  int size_recv;
  grub_net_tcp_socket_t sock;
  char *filename;
  grub_err_t err;
  char *errmsg;
  int chunked;
  grub_size_t chunk_rem;
  int in_chunk_len;
} *http_data_t;

static grub_off_t
have_ahead (struct grub_file *file)
{
  grub_net_t net = file->device->net;
  grub_off_t ret = net->offset;
  struct grub_net_packet *pack;
  for (pack = net->packs.first; pack; pack = pack->next)
    ret += pack->nb->tail - pack->nb->data;
  return ret;
}

static grub_err_t
parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len)
{
  char *end = ptr + len;
  while (end > ptr && *(end - 1) == '\r')
    end--;
  *end = 0;
  /* Trailing CRLF.  */
  if (data->in_chunk_len == 1)
    {
      data->in_chunk_len = 2;
      return GRUB_ERR_NONE;
    }
  if (data->in_chunk_len == 2)
    {
      data->chunk_rem = grub_strtoul (ptr, 0, 16);
      grub_errno = GRUB_ERR_NONE;
      if (data->chunk_rem == 0)
	{
	  file->device->net->eof = 1;
	  file->device->net->stall = 1;
	  if (file->size == GRUB_FILE_SIZE_UNKNOWN)
	    file->size = have_ahead (file);
	}
      data->in_chunk_len = 0;
      return GRUB_ERR_NONE;
    }
  if (ptr == end)
    {
      data->headers_recv = 1;
      if (data->chunked)
	data->in_chunk_len = 2;
      return GRUB_ERR_NONE;
    }

  if (!data->first_line_recv)
    {
      int code;
      if (grub_memcmp (ptr, "HTTP/1.1 ", sizeof ("HTTP/1.1 ") - 1) != 0)
	{
	  data->errmsg = grub_strdup (_("unsupported HTTP response"));
	  data->first_line_recv = 1;
	  return GRUB_ERR_NONE;
	}
      ptr += sizeof ("HTTP/1.1 ") - 1;
      code = grub_strtoul (ptr, &ptr, 10);
      if (grub_errno)
	return grub_errno;
      switch (code)
	{
	case 200:
	case 206:
	  break;
	case 404:
	  data->err = GRUB_ERR_FILE_NOT_FOUND;
	  data->errmsg = grub_xasprintf (_("file `%s' not found"), data->filename);
	  return GRUB_ERR_NONE;
	default:
	  data->err = GRUB_ERR_NET_UNKNOWN_ERROR;
	  /* TRANSLATORS: GRUB HTTP code is pretty young. So even perfectly
	     valid answers like 403 will trigger this very generic message.  */
	  data->errmsg = grub_xasprintf (_("unsupported HTTP error %d: %s"),
					 code, ptr);
	  return GRUB_ERR_NONE;
	}
      data->first_line_recv = 1;
      return GRUB_ERR_NONE;
    }
  if (grub_memcmp (ptr, "Content-Length: ", sizeof ("Content-Length: ") - 1)
      == 0 && !data->size_recv)
    {
      ptr += sizeof ("Content-Length: ") - 1;
      file->size = grub_strtoull (ptr, &ptr, 10);
      data->size_recv = 1;
      return GRUB_ERR_NONE;
    }
  if (grub_memcmp (ptr, "Transfer-Encoding: chunked",
		   sizeof ("Transfer-Encoding: chunked") - 1) == 0)
    {
      data->chunked = 1;
      return GRUB_ERR_NONE;
    }

  return GRUB_ERR_NONE;  
}

static void
http_err (grub_net_tcp_socket_t sock __attribute__ ((unused)),
	  void *f)
{
  grub_file_t file = f;
  http_data_t data = file->data;

  if (data->sock)
    grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
  data->sock = 0;
  if (data->current_line)
    grub_free (data->current_line);
  data->current_line = 0;
  file->device->net->eof = 1;
  file->device->net->stall = 1;
  if (file->size == GRUB_FILE_SIZE_UNKNOWN)
    file->size = have_ahead (file);
}

static grub_err_t
http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
	      struct grub_net_buff *nb,
	      void *f)
{
  grub_file_t file = f;
  http_data_t data = file->data;
  grub_err_t err;

  if (!data->sock)
    {
      grub_netbuff_free (nb);
      return GRUB_ERR_NONE;
    }

  while (1)
    {
      char *ptr = (char *) nb->data;
      if ((!data->headers_recv || data->in_chunk_len) && data->current_line)
	{
	  int have_line = 1;
	  char *t;
	  ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data);
	  if (ptr)
	    ptr++;
	  else
	    {
	      have_line = 0;
	      ptr = (char *) nb->tail;
	    }
	  t = grub_realloc (data->current_line,
			    data->current_line_len + (ptr - (char *) nb->data));
	  if (!t)
	    {
	      grub_netbuff_free (nb);
	      grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
	      return grub_errno;
	    }
	      
	  data->current_line = t;
	  grub_memcpy (data->current_line + data->current_line_len,
		       nb->data, ptr - (char *) nb->data);
	  data->current_line_len += ptr - (char *) nb->data;
	  if (!have_line)
	    {
	      grub_netbuff_free (nb);
	      return GRUB_ERR_NONE;
	    }
	  err = parse_line (file, data, data->current_line,
			    data->current_line_len);
	  grub_free (data->current_line);
	  data->current_line = 0;
	  data->current_line_len = 0;
	  if (err)
	    {
	      grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
	      grub_netbuff_free (nb);
	      return err;
	    }
	}

      while (ptr < (char *) nb->tail && (!data->headers_recv
					 || data->in_chunk_len))
	{
	  char *ptr2;
	  ptr2 = grub_memchr (ptr, '\n', (char *) nb->tail - ptr);
	  if (!ptr2)
	    {
	      data->current_line = grub_malloc ((char *) nb->tail - ptr);
	      if (!data->current_line)
		{
		  grub_netbuff_free (nb);
		  grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
		  return grub_errno;
		}
	      data->current_line_len = (char *) nb->tail - ptr;
	      grub_memcpy (data->current_line, ptr, data->current_line_len);
	      grub_netbuff_free (nb);
	      return GRUB_ERR_NONE;
	    }
	  err = parse_line (file, data, ptr, ptr2 - ptr);
	  if (err)
	    {
	      grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
	      grub_netbuff_free (nb);
	      return err;
	    }
	  ptr = ptr2 + 1;
	}

      if (((char *) nb->tail - ptr) <= 0)
	{
	  grub_netbuff_free (nb);
	  return GRUB_ERR_NONE;
	} 
      err = grub_netbuff_pull (nb, ptr - (char *) nb->data);
      if (err)
	{
	  grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
	  grub_netbuff_free (nb);
	  return err;
	}
      if (!(data->chunked && (grub_ssize_t) data->chunk_rem
	    < nb->tail - nb->data))
	{
	  grub_net_put_packet (&file->device->net->packs, nb);
	  if (file->device->net->packs.count >= 20)
	    file->device->net->stall = 1;

	  if (file->device->net->packs.count >= 100)
	    grub_net_tcp_stall (data->sock);

	  if (data->chunked)
	    data->chunk_rem -= nb->tail - nb->data;
	  return GRUB_ERR_NONE;
	}
      if (data->chunk_rem)
	{
	  struct grub_net_buff *nb2;
	  nb2 = grub_netbuff_alloc (data->chunk_rem);
	  if (!nb2)
	    return grub_errno;
	  grub_netbuff_put (nb2, data->chunk_rem);
	  grub_memcpy (nb2->data, nb->data, data->chunk_rem);
	  if (file->device->net->packs.count >= 20)
	    {
	      file->device->net->stall = 1;
	      grub_net_tcp_stall (data->sock);
	    }

	  grub_net_put_packet (&file->device->net->packs, nb2);
	  grub_netbuff_pull (nb, data->chunk_rem);
	}
      data->in_chunk_len = 1;
    }
}

static grub_err_t
http_establish (struct grub_file *file, grub_off_t offset, int initial)
{
  http_data_t data = file->data;
  grub_uint8_t *ptr;
  int i;
  struct grub_net_buff *nb;
  grub_err_t err;

  nb = grub_netbuff_alloc (GRUB_NET_TCP_RESERVE_SIZE
			   + sizeof ("GET ") - 1
			   + grub_strlen (data->filename)
			   + sizeof (" HTTP/1.1\r\nHost: ") - 1
			   + grub_strlen (file->device->net->server)
			   + sizeof ("\r\nUser-Agent: " PACKAGE_STRING
				     "\r\n") - 1
			   + sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX"
				     "-\r\n\r\n"));
  if (!nb)
    return grub_errno;

  grub_netbuff_reserve (nb, GRUB_NET_TCP_RESERVE_SIZE);
  ptr = nb->tail;
  err = grub_netbuff_put (nb, sizeof ("GET ") - 1);
  if (err)
    {
      grub_netbuff_free (nb);
      return err;
    }
  grub_memcpy (ptr, "GET ", sizeof ("GET ") - 1);

  ptr = nb->tail;

  err = grub_netbuff_put (nb, grub_strlen (data->filename));
  if (err)
    {
      grub_netbuff_free (nb);
      return err;
    }
  grub_memcpy (ptr, data->filename, grub_strlen (data->filename));

  ptr = nb->tail;
  err = grub_netbuff_put (nb, sizeof (" HTTP/1.1\r\nHost: ") - 1);
  if (err)
    {
      grub_netbuff_free (nb);
      return err;
    }
  grub_memcpy (ptr, " HTTP/1.1\r\nHost: ",
	       sizeof (" HTTP/1.1\r\nHost: ") - 1);

  ptr = nb->tail;
  err = grub_netbuff_put (nb, grub_strlen (file->device->net->server));
  if (err)
    {
      grub_netbuff_free (nb);
      return err;
    }
  grub_memcpy (ptr, file->device->net->server,
	       grub_strlen (file->device->net->server));

  ptr = nb->tail;
  err = grub_netbuff_put (nb, 
			  sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n")
			  - 1);
  if (err)
    {
      grub_netbuff_free (nb);
      return err;
    }
  grub_memcpy (ptr, "\r\nUser-Agent: " PACKAGE_STRING "\r\n",
	       sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n") - 1);
  if (!initial)
    {
      ptr = nb->tail;
      grub_snprintf ((char *) ptr,
		     sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX-"
			     "\r\n"),
		     "Range: bytes=%" PRIuGRUB_UINT64_T "-\r\n",
		     offset);
      grub_netbuff_put (nb, grub_strlen ((char *) ptr));
    }
  ptr = nb->tail;
  grub_netbuff_put (nb, 2);
  grub_memcpy (ptr, "\r\n", 2);

  data->sock = grub_net_tcp_open (file->device->net->server,
				  HTTP_PORT, http_receive,
				  http_err, http_err,
				  file);
  if (!data->sock)
    {
      grub_netbuff_free (nb);
      return grub_errno;
    }

  //  grub_net_poll_cards (5000);

  err = grub_net_send_tcp_packet (data->sock, nb, 1);
  if (err)
    {
      grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
      return err;
    }

  for (i = 0; !data->headers_recv && i < 100; i++)
    {
      grub_net_tcp_retransmit ();
      grub_net_poll_cards (300, &data->headers_recv);
    }

  if (!data->headers_recv)
    {
      grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
      if (data->err)
	{
	  char *str = data->errmsg;
	  err = grub_error (data->err, "%s", str);
	  grub_free (str);
	  data->errmsg = 0;
	  return data->err;
	}
      return grub_error (GRUB_ERR_TIMEOUT, N_("time out opening `%s'"), data->filename);
    }
  return GRUB_ERR_NONE;
}

static grub_err_t
http_seek (struct grub_file *file, grub_off_t off)
{
  struct http_data *old_data, *data;
  grub_err_t err;
  old_data = file->data;
  /* FIXME: Reuse socket?  */
  if (old_data->sock)
    grub_net_tcp_close (old_data->sock, GRUB_NET_TCP_ABORT);
  old_data->sock = 0;

  while (file->device->net->packs.first)
    {
      grub_netbuff_free (file->device->net->packs.first->nb);
      grub_net_remove_packet (file->device->net->packs.first);
    }

  file->device->net->stall = 0;
  file->device->net->eof = 0;
  file->device->net->offset = off;

  data = grub_zalloc (sizeof (*data));
  if (!data)
    return grub_errno;

  data->size_recv = 1;
  data->filename = old_data->filename;
  if (!data->filename)
    {
      grub_free (data);
      file->data = 0;
      return grub_errno;
    }
  grub_free (old_data);

  file->data = data;
  err = http_establish (file, off, 0);
  if (err)
    {
      grub_free (data->filename);
      grub_free (data);
      file->data = 0;
      return err;
    }
  return GRUB_ERR_NONE;
}

static grub_err_t
http_open (struct grub_file *file, const char *filename)
{
  grub_err_t err;
  struct http_data *data;

  data = grub_zalloc (sizeof (*data));
  if (!data)
    return grub_errno;
  file->size = GRUB_FILE_SIZE_UNKNOWN;

  data->filename = grub_strdup (filename);
  if (!data->filename)
    {
      grub_free (data);
      return grub_errno;
    }

  file->not_easily_seekable = 0;
  file->data = data;

  err = http_establish (file, 0, 1);
  if (err)
    {
      grub_free (data->filename);
      grub_free (data);
      return err;
    }

  return GRUB_ERR_NONE;
}

static grub_err_t
http_close (struct grub_file *file)
{
  http_data_t data = file->data;

  if (!data)
    return GRUB_ERR_NONE;

  if (data->sock)
    grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
  if (data->current_line)
    grub_free (data->current_line);
  grub_free (data->filename);
  grub_free (data);
  return GRUB_ERR_NONE;
}

static grub_err_t
http_packets_pulled (struct grub_file *file)
{
  http_data_t data = file->data;

  if (file->device->net->packs.count >= 20)
    return 0;

  if (!file->device->net->eof)
    file->device->net->stall = 0;
  if (data && data->sock)
    grub_net_tcp_unstall (data->sock);
  return 0;
}

static struct grub_net_app_protocol grub_http_protocol = 
  {
    .name = "http",
    .open = http_open,
    .close = http_close,
    .seek = http_seek,
    .packets_pulled = http_packets_pulled
  };

GRUB_MOD_INIT (http)
{
  grub_net_app_level_register (&grub_http_protocol);
}

GRUB_MOD_FINI (http)
{
  grub_net_app_level_unregister (&grub_http_protocol);
}
