#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>
#include <disk.h>

static Disk*
mkwidth(Disk *disk)
{
	char buf[40];

	sprint(buf, "%lld", disk->size);
	disk->width = strlen(buf);
	return disk;
}

/*
 * Discover the disk geometry by various sleazeful means.
 * 
 * First, if there is a partition table in sector 0,
 * see if all the partitions have the same end head
 * and sector; if so, we'll assume that that's the 
 * right count.
 * 
 * If that fails, we'll try looking at the geometry that the ATA
 * driver supplied, if any, and translate that as a
 * BIOS might. 
 * 
 * If that too fails, which should only happen on a SCSI
 * disk with no currently defined partitions, we'll try
 * various common (h, s) pairs used by BIOSes when faking
 * the geometries.
 */
typedef struct Table  Table;
typedef struct Tentry Tentry;
struct Tentry {
	uchar	active;			/* active flag */
	uchar	starth;			/* starting head */
	uchar	starts;			/* starting sector */
	uchar	startc;			/* starting cylinder */
	uchar	type;			/* partition type */
	uchar	endh;			/* ending head */
	uchar	ends;			/* ending sector */
	uchar	endc;			/* ending cylinder */
	uchar	xlba[4];			/* starting LBA from beginning of disc */
	uchar	xsize[4];		/* size in sectors */
};
enum {
	Toffset		= 446,		/* offset of partition table in sector */
	Magic0		= 0x55,
	Magic1		= 0xAA,
	NTentry		= 4
};
struct Table {
	Tentry	entry[NTentry];
	uchar	magic[2];
};
static int
partitiongeometry(Disk *disk)
{
	char *rawname;
	int i, h, rawfd, s;
	uchar buf[512];
	Table *t;

	t = (Table*)(buf + Toffset);

	/*
	 * look for an MBR first in the /dev/sdXX/data partition, otherwise
	 * attempt to fall back on the current partition.
	 */
	rawname = malloc(strlen(disk->prefix) + 5);	/* prefix + "data" + nul */
	if(rawname == nil)
		return -1;

	strcpy(rawname, disk->prefix);
	strcat(rawname, "data");
	rawfd = open(rawname, OREAD);
	free(rawname);
	if(rawfd >= 0
	&& seek(rawfd, 0, 0) >= 0
	&& readn(rawfd, buf, 512) == 512
	&& t->magic[0] == Magic0
	&& t->magic[1] == Magic1) {
		close(rawfd);
	} else {
		if(rawfd >= 0)
			close(rawfd);
		if(seek(disk->fd, 0, 0) < 0
		|| readn(disk->fd, buf, 512) != 512
		|| t->magic[0] != Magic0
		|| t->magic[1] != Magic1) {
			return -1;
		}
	}

	h = s = -1;
	for(i=0; i<NTentry; i++) {
		if(t->entry[i].type == 0)
			continue;

		t->entry[i].ends &= 63;
		if(h == -1) {
			h = t->entry[i].endh;
			s = t->entry[i].ends;
		} else {
			/*
			 * Only accept the partition info if every
			 * partition is consistent.
			 */
			if(h != t->entry[i].endh || s != t->entry[i].ends)
				return -1;
		}
	}

	if(h == -1)
		return -1;

	disk->h = h+1;	/* heads count from 0 */
	disk->s = s;	/* sectors count from 1 */
	disk->c = disk->secs / (disk->h*disk->s);
	disk->chssrc = Gpart;
	return 0;
}

/*
 * If there is ATA geometry, use it, perhaps massaged.
 */
static int
drivergeometry(Disk *disk)
{
	int m;

	if(disk->c == 0 || disk->h == 0 || disk->s == 0)
		return -1;

	disk->chssrc = Gdisk;
	if(disk->c < 1024)
		return 0;

	switch(disk->h) {
	case 15:
		disk->h = 255;
		disk->c /= 17;
		return 0;
	}

	for(m = 2; m*disk->h < 256; m *= 2) {
		if(disk->c/m < 1024) {
			disk->c /= m;
			disk->h *= m;
			return 0;
		}
	}

	/* set to 255, 63 and be done with it */
	disk->h = 255;
	disk->s = 63;
	disk->c = disk->secs / (disk->h * disk->s);
	return 0;
}

/*
 * There's no ATA geometry and no partitions.
 * Our guess is as good as anyone's.
 */
static struct {
	int h;
	int s;
} guess[] = {
	64, 32,
	64, 63,
	128, 63,
	255, 63,
};
static int
guessgeometry(Disk *disk)
{
	int i;
	long c;

	disk->chssrc = Gguess;
	c = 1024;
	for(i=0; i<nelem(guess); i++)
		if(c*guess[i].h*guess[i].s >= disk->secs) {
			disk->h = guess[i].h;
			disk->s = guess[i].s;
			disk->c = disk->secs / (disk->h * disk->s);
			return 0;
		}

	/* use maximum values */
	disk->h = 255;
	disk->s = 63;
	disk->c = disk->secs / (disk->h * disk->s);
	return 0;
}

static void
findgeometry(Disk *disk)
{
	if(partitiongeometry(disk) < 0
	&& drivergeometry(disk) < 0
	&& guessgeometry(disk) < 0) {	/* can't happen */
		print("we're completely confused about your disk; sorry\n");
		assert(0);
	}
}

static Disk*
openfile(Disk *disk)
{
	Dir *d;

	if((d = dirfstat(disk->fd)) == nil){
		free(disk);
		return nil;
	}

	disk->secsize = 512;
	disk->size = d->length;
	disk->secs = disk->size / disk->secsize;
	disk->offset = 0;
	free(d);

	findgeometry(disk);
	return mkwidth(disk);
}

static Disk*
opensd(Disk *disk)
{
	Biobuf b;
	char *p, *f[10];
	int nf;

	Binit(&b, disk->ctlfd, OREAD);
	while(p = Brdline(&b, '\n')) {
		p[Blinelen(&b)-1] = '\0';
		nf = tokenize(p, f, nelem(f));
		if(nf >= 3 && strcmp(f[0], "geometry") == 0) {
			disk->secsize = strtoll(f[2], 0, 0);
			if(nf >= 6) {
				disk->c = strtol(f[3], 0, 0);
				disk->h = strtol(f[4], 0, 0);
				disk->s = strtol(f[5], 0, 0);
			}
		}
		if(nf >= 4 && strcmp(f[0], "part") == 0 && strcmp(f[1], disk->part) == 0) {
			disk->offset = strtoll(f[2], 0, 0);
			disk->secs = strtoll(f[3], 0, 0) - disk->offset;
		}
	}

	
	disk->size = disk->secs * disk->secsize;
	if(disk->size <= 0) {
		strcpy(disk->part, "");
		disk->type = Tfile;
		return openfile(disk);
	}

	findgeometry(disk);
	return mkwidth(disk);
}

Disk*
opendisk(char *disk, int rdonly, int noctl)
{
	char *p, *q;
	Disk *d;

	d = malloc(sizeof(*d));
	if(d == nil)
		return nil;

	d->fd = d->wfd = d->ctlfd = -1;
	d->rdonly = rdonly;

	d->fd = open(disk, OREAD);
	if(d->fd < 0) {
		werrstr("cannot open disk file");
		free(d);
		return nil;
	}

	if(rdonly == 0) {
		d->wfd = open(disk, OWRITE);
		if(d->wfd < 0)
			d->rdonly = 1;
	}

	if(noctl)
		return openfile(d);

	p = malloc(strlen(disk) + 4);	/* 4: slop for "ctl\0" */
	if(p == nil) {
		close(d->wfd);
		close(d->fd);
		free(d);
		return nil;
	}
	strcpy(p, disk);

	/* check for floppy(3) disk */
	if(strlen(p) >= 7) {
		q = p+strlen(p)-7;
		if(q[0] == 'f' && q[1] == 'd' && isdigit((uchar)q[2]) && strcmp(q+3, "disk") == 0) {
			strcpy(q+3, "ctl");
			if((d->ctlfd = open(p, ORDWR)) >= 0) {
				*q = '\0';
				d->prefix = p;
				d->type = Tfloppy;
				return openfile(d);
			}
		}
	}

	/* attempt to find sd(3) disk or partition */
	if(q = strrchr(p, '/'))
		q++;
	else
		q = p;

	strcpy(q, "ctl");
	if((d->ctlfd = open(p, ORDWR)) >= 0) {
		*q = '\0';
		d->prefix = p;
		d->type = Tsd;
		d->part = strdup(disk+(q-p));
		if(d->part == nil){
			close(d->ctlfd);
			close(d->wfd);
			close(d->fd);
			free(p);
			free(d);
			return nil;
		}
		return opensd(d);
	}

	*q = '\0';
	d->prefix = p;
	/* assume we just have a normal file */
	d->type = Tfile;
	return openfile(d);
}

