#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/stat.h>
#include <linux/fs.h>
#include <linux/cdrom.h>
#include <linux/fd.h>

#include "kinit.h"
#include "do_mounts.h"
#include "fstype.h"
#include "zlib.h"

#define BUF_SZ		65536

static void wait_for_key(void)
{
	/* Wait until the user presses Enter */
	while (getchar() != '\n')
		;
}

static int change_disk(const char *devpath, int rfd, int disk)
{
	/* Try to eject and/or quiesce the device */
	sync();
	if (ioctl(rfd, FDEJECT, 0)) {
		if (errno == ENOTTY) {
			/* Not a floppy */
			ioctl(rfd, CDROMEJECT, 0);
		} else {
			/* Non-ejectable floppy */
			ioctl(rfd, FDRESET, FD_RESET_IF_NEEDED);
		}
	}
	close(rfd);

	fprintf(stderr,
		"\nPlease insert disk %d for ramdisk and press Enter...", disk);
	wait_for_key();

	return open(devpath, O_RDONLY);
}

/* Also used in initrd.c */
int load_ramdisk_compressed(const char *devpath, FILE * wfd,
			    off_t ramdisk_start)
{
	int rfd = -1;
	unsigned long long ramdisk_size, ramdisk_left;
	int disk = 1;
	ssize_t bytes;
	int rv;
	unsigned char in_buf[BUF_SZ], out_buf[BUF_SZ];
	z_stream zs;

	zs.zalloc = Z_NULL;	/* Use malloc() */
	zs.zfree = Z_NULL;	/* Use free() */
	zs.next_in = Z_NULL;	/* No data read yet */
	zs.avail_in = 0;
	zs.next_out = out_buf;
	zs.avail_out = BUF_SZ;

	if (inflateInit2(&zs, 32 + 15) != Z_OK)
		goto err1;

	rfd = open(devpath, O_RDONLY);
	if (rfd < 0)
		goto err2;

	/* Set to the size of the medium, or "infinite" */
	if (ioctl(rfd, BLKGETSIZE64, &ramdisk_size))
		ramdisk_size = ~0ULL;

	do {
		/* Purge the output preferentially over reading new
		   input, so we don't end up overrunning the input by
		   accident and demanding a new disk which doesn't
		   exist... */
		if (zs.avail_out == 0) {
			_fwrite(out_buf, BUF_SZ, wfd);
			zs.next_out = out_buf;
			zs.avail_out = BUF_SZ;
		} else if (zs.avail_in == 0) {
			if (ramdisk_start >= ramdisk_size) {
				rfd = change_disk(devpath, rfd, ++disk);
				if (rfd < 0)
					goto err2;

				if (ioctl(rfd, BLKGETSIZE64, &ramdisk_size))
					ramdisk_size = ~0ULL;
				ramdisk_start = 0;
				dprintf("New size = %llu\n", ramdisk_size);
			}
			do {
				ramdisk_left = ramdisk_size - ramdisk_start;
				bytes = min(ramdisk_left,
					    (unsigned long long)BUF_SZ);
				bytes = pread(rfd, in_buf, bytes,
					      ramdisk_start);
			} while (bytes == -1 && errno == EINTR);
			if (bytes <= 0)
				goto err2;
			ramdisk_start += bytes;
			zs.next_in = in_buf;
			zs.avail_in = bytes;

			/* Print dots if we're reading from a real block device */
			if (ramdisk_size != ~0ULL)
				putc('.', stderr);
		}
		rv = inflate(&zs, Z_SYNC_FLUSH);
	} while (rv == Z_OK || rv == Z_BUF_ERROR);

	dprintf("kinit: inflate returned %d\n", rv);

	if (rv != Z_STREAM_END)
		goto err2;

	/* Write the last */
	_fwrite(out_buf, BUF_SZ - zs.avail_out, wfd);
	dprintf("kinit: writing %d bytes\n", BUF_SZ - zs.avail_out);

	inflateEnd(&zs);
	return 0;

err2:
	inflateEnd(&zs);
err1:
	return -1;
}

static int
load_ramdisk_raw(const char *devpath, FILE * wfd, off_t ramdisk_start,
		 unsigned long long fssize)
{
	unsigned long long ramdisk_size, ramdisk_left;
	int disk = 1;
	ssize_t bytes;
	unsigned char buf[BUF_SZ];
	int rfd;

	rfd = open(devpath, O_RDONLY);
	if (rfd < 0)
		return -1;

	/* Set to the size of the medium, or "infinite" */
	if (ioctl(rfd, BLKGETSIZE64, &ramdisk_size))
		ramdisk_size = ~0ULL;

	dprintf("start: %llu  size: %llu  fssize: %llu\n",
		ramdisk_start, ramdisk_size, fssize);

	while (fssize) {

		if (ramdisk_start >= ramdisk_size) {
			rfd = change_disk(devpath, rfd, ++disk);
			if (rfd < 0)
				return -1;

			if (ioctl(rfd, BLKGETSIZE64, &ramdisk_size))
				ramdisk_size = ~0ULL;
			ramdisk_start = 0;
		}

		do {
			ramdisk_left =
			    min(ramdisk_size - ramdisk_start, fssize);
			bytes = min(ramdisk_left, (unsigned long long)BUF_SZ);
			bytes = pread(rfd, buf, bytes, ramdisk_start);
		} while (bytes == -1 && errno == EINTR);
		if (bytes <= 0)
			break;
		_fwrite(buf, bytes, wfd);

		ramdisk_start += bytes;
		fssize -= bytes;

		/* Print dots if we're reading from a real block device */
		if (ramdisk_size != ~0ULL)
			putc('.', stderr);
	}

	return !!fssize;
}

int ramdisk_load(int argc, char *argv[])
{
	const char *arg_prompt_ramdisk = get_arg(argc, argv, "prompt_ramdisk=");
	const char *arg_ramdisk_blocksize =
	    get_arg(argc, argv, "ramdisk_blocksize=");
	const char *arg_ramdisk_start = get_arg(argc, argv, "ramdisk_start=");
	const char *arg_ramdisk_device = get_arg(argc, argv, "ramdisk_device=");

	int prompt_ramdisk = arg_prompt_ramdisk ? atoi(arg_prompt_ramdisk) : 0;
	int ramdisk_blocksize =
	    arg_ramdisk_blocksize ? atoi(arg_ramdisk_blocksize) : 512;
	off_t ramdisk_start =
	    arg_ramdisk_start
	    ? strtoumax(arg_ramdisk_start, NULL, 10) * ramdisk_blocksize : 0;
	const char *ramdisk_device =
	    arg_ramdisk_device ? arg_ramdisk_device : "/dev/fd0";

	dev_t ramdisk_dev;
	int rfd;
	FILE *wfd;
	const char *fstype;
	unsigned long long fssize;
	int is_gzip = 0;
	int err;

	if (prompt_ramdisk) {
		fprintf(stderr,
			"Please insert disk for ramdisk and press Enter...");
		wait_for_key();
	}

	ramdisk_dev = name_to_dev_t(ramdisk_device);
	if (!ramdisk_dev) {
		fprintf(stderr,
			"Failure loading ramdisk: unknown device: %s\n",
			ramdisk_device);
		return 0;
	}

	create_dev("/dev/rddev", ramdisk_dev);
	create_dev("/dev/ram0", Root_RAM0);
	rfd = open("/dev/rddev", O_RDONLY);
	wfd = fopen("/dev/ram0", "w");

	if (rfd < 0 || !wfd) {
		perror("Could not open ramdisk device");
		return 0;
	}

	/* Check filesystem type */
	if (identify_fs(rfd, &fstype, &fssize, ramdisk_start) ||
	    (fssize == 0 && !(is_gzip = !strcmp(fstype, "gzip")))) {
		fprintf(stderr,
			"Failure loading ramdisk: unknown filesystem type\n");
		close(rfd);
		fclose(wfd);
		return 0;
	}

	dprintf("kinit: ramdisk is %s, size %llu\n", fstype, fssize);

	fprintf(stderr, "Loading ramdisk (%s) ...", is_gzip ? "gzip" : "raw");

	close(rfd);

	if (is_gzip)
		err = load_ramdisk_compressed("/dev/rddev", wfd, ramdisk_start);
	else
		err = load_ramdisk_raw("/dev/rddev", wfd,
				       ramdisk_start, fssize);

	fclose(wfd);

	putc('\n', stderr);

	if (err) {
		perror("Failure loading ramdisk");
		return 0;
	}

	return 1;
}
