/*
    libparted - a library for manipulating disk partitions
    Copyright (C) 2006, 2007 Free Software Foundation, Inc.

    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 2 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, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

#include <config.h>

#include <parted/parted.h>
#include <parted/debug.h>
#include <parted/beos.h>

/* POSIX headers */
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

/* BeOS APIs */
#include <drivers/Drivers.h>

/* ZETA R1+ APIs */
#if B_ZETA_VERSION >= B_ZETA_VERSION_1_0_0
#  include <device/ata_info.h>
#endif

#if ENABLE_NLS
#  include <libintl.h>
#  define _(String) dgettext (PACKAGE, String)
#else
#  define _(String) (String)
#endif /* ENABLE_NLS */

static void
_scan_for_disks(const char* path)
{
	char subdir[PATH_MAX];
	dirent_t* entp;
	size_t pos;
	DIR* dirp;
	
	if ((dirp=opendir(path)) != NULL)
	{
		/* Build first part of path */
		strcpy(subdir, path);
		strcat(subdir, "/");
		pos = strlen(subdir);

		/* Check all directory entries.. */
		while((entp=readdir(dirp)) != NULL)
		{
			/* If they start with '.' just skip */
			if (entp->d_name[0] == '.')
				continue;

			strcpy(subdir+pos, entp->d_name);
			
			/* /dev/disk/.../raw are the complete disks
				we're interested in */
			if (strcmp(entp->d_name, "raw") == 0)
				_ped_device_probe(subdir);
			else	/* If not 'raw', it most often will
						be another subdir */
				_scan_for_disks(subdir);
		}
		
		closedir(dirp);
	}
}

static void
_flush_cache(PedDevice* dev)
{
	int fd;
	if ((fd=open(dev->path, O_RDONLY)) < 0)
	{
		ioctl(fd, B_FLUSH_DRIVE_CACHE);
		close(fd);
	}
}

#if B_ZETA_VERSION >= B_ZETA_VERSION_1_0_0
static int
_device_init_ata(PedDevice* dev)
{
	ata_device_infoblock ide_info;
	int maxlen, len, idx, fd;
	char buf[256];

	/* Try and get information about device from ATA(PI) driver */	
	if ((fd=open(dev->path, O_RDONLY)) < 0)
		goto ata_error;
	
	if (ioctl(fd, B_ATA_GET_DEVICE_INFO, &ide_info, sizeof(ide_info)) < 0)
		goto ata_error_close;

	close(fd);
	
	/* Copy 'logical' dimensions */
	dev->bios_geom.cylinders = ide_info.cylinders;
	dev->bios_geom.heads = ide_info.heads;
	dev->bios_geom.sectors = ide_info.sectors;
	
	/* Copy used dimensions */
	dev->hw_geom.cylinders = ide_info.current_cylinders;
	dev->hw_geom.heads = ide_info.current_heads;
	dev->hw_geom.sectors = ide_info.current_sectors;

	/* Copy total number of sectors */
	if (ide_info._48_bit_addresses_supported)
		dev->length = ide_info.LBA48_total_sectors;
	else if (ide_info.LBA_supported)
		dev->length = ide_info.LBA_total_sectors;
	else
		dev->length = ide_info.cylinders * 
				ide_info.heads * 
				ide_info.sectors;

	dev->sector_size =
	dev->phys_sector_size = PED_SECTOR_SIZE_DEFAULT;

	/* Use sensible model */
	maxlen=sizeof(ide_info.model_number);
	strncpy(buf, ide_info.model_number, maxlen);
	buf[maxlen] = '\0';
	
	for (len=-1, idx=maxlen-1; idx > 0 && len < 0; idx--)
		if (buf[idx] > 0x20)
			len = idx;
	
	buf[(len == -1) ? 0 : len+1] = '\0';				
	
	dev->model = strdup(buf);

	return PED_DEVICE_IDE;

ata_error_close:
	close(fd);

ata_error:
	return 0;
}
#endif 

static int
_device_init_generic_blkdev(PedDevice* dev)
{
	device_geometry bios, os;
	int got_bios_info = 0;
	int fd;

	/* Try and get information about device from ATA(PI) driver */	
	if ((fd=open(dev->path, O_RDONLY)) < 0)
		goto blkdev_error;
	
	/* B_GET_GEOMETRY is mandatory */
	if (ioctl(fd, B_GET_GEOMETRY, &os, sizeof(os)) < 0)
		goto blkdev_error_close;

	/* B_GET_BIOS_GEOMETRY is optional */
	if (!ioctl(fd, B_GET_BIOS_GEOMETRY, &bios, sizeof(bios)))
		got_bios_info = 1;

	close(fd);
	
	dev->hw_geom.cylinders = os.cylinder_count;
	dev->hw_geom.heads = os.head_count;
	dev->hw_geom.sectors = os.sectors_per_track;
	
	dev->sector_size =
	dev->phys_sector_size = os.bytes_per_sector;
	
	if (got_bios_info)
	{
		dev->bios_geom.cylinders = bios.cylinder_count;
		dev->bios_geom.heads = bios.head_count;
		dev->bios_geom.sectors = bios.sectors_per_track;
	}
	else
		dev->bios_geom = dev->hw_geom;

	dev->model = strdup("");

	return PED_DEVICE_IDE;
	
blkdev_error_close:
	close(fd);
	
blkdev_error:
	return 0;
}

static int
_device_init_blkdev(PedDevice* dev)
{
	int type;

#if B_ZETA_VERSION >= B_ZETA_VERSION_1_0_0
	if (!(type=_device_init_ata(dev)))
#endif
	type = _device_init_generic_blkdev(dev);

	return type;
}

static int
_device_init_file(PedDevice* dev, struct stat* dev_statp)
{
	if (!dev_statp->st_size)
		return 0;

	dev->sector_size =
	dev->phys_sector_size = PED_SECTOR_SIZE_DEFAULT;

	dev->length = dev_statp->st_size / PED_SECTOR_SIZE_DEFAULT;

	dev->bios_geom.cylinders = dev->length / (4 * 32);
	dev->bios_geom.heads = 4;
	dev->bios_geom.sectors = 32;
	dev->hw_geom = dev->bios_geom;

	dev->model = strdup(_("Disk Image"));
	
	return PED_DEVICE_FILE;
}

static int
_device_init(PedDevice* dev)
{
	struct stat dev_stat;
	int type = 0;
	
	/* Check if we're a regular file */	
	if (stat(dev->path, &dev_stat) < 0)
		goto done;

	if (S_ISBLK(dev_stat.st_mode) || S_ISCHR(dev_stat.st_mode))
		type = _device_init_blkdev(dev);
	else if (S_ISREG(dev_stat.st_mode))
		type = _device_init_file(dev,&dev_stat);

done:
	return type;
}


static PedDevice*
beos_new (const char* path)
{
	struct stat stat_info;
	PedDevice* dev;

	PED_ASSERT(path != NULL, return NULL);

	dev = (PedDevice*) ped_malloc (sizeof (PedDevice));
	if (!dev)
		goto error;

	dev->path = strdup(path);
	if (!dev->path)
		goto error_free_dev;

	dev->arch_specific 
		= (BEOSSpecific*) ped_malloc(sizeof(BEOSSpecific));
	if (dev->arch_specific == NULL)
		goto error_free_path;

	dev->open_count = 0;
	dev->read_only = 0;
	dev->external_mode = 0;
	dev->dirty = 0;
	dev->boot_dirty = 0;

	if ((dev->type=_device_init(dev)) <= 0)
		goto error_free_arch_specific;

	/* All OK! */
	return dev;
	
error_free_arch_specific:
	ped_free (dev->arch_specific);
	
error_free_path:
	ped_free (dev->path);
	
error_free_dev:
	ped_free (dev);
	
error:
	return NULL;
}

static void
beos_destroy (PedDevice* dev)
{
	ped_free (dev->arch_specific);
	ped_free (dev->path);
	ped_free (dev->model);
	ped_free (dev);
}

static int
beos_is_busy (PedDevice* dev)
{
	return 1;
}

static int
beos_open (PedDevice* dev)
{
	BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev);

retry:
	arch_specific->fd = open(dev->path, O_RDWR);
	if (arch_specific->fd == -1) {
		char* rw_error_msg = strerror(errno);

		arch_specific->fd = open (dev->path, O_RDONLY);
		if (arch_specific->fd == -1) {
			if (ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_RETRY_CANCEL,
					_("Error opening %s: %s"),
					dev->path, strerror (errno))
					!= PED_EXCEPTION_RETRY) {
						return 0;
					} else {
						goto retry;
					}
		} else {
			ped_exception_throw (
				PED_EXCEPTION_WARNING,
				PED_EXCEPTION_OK,
				_("Unable to open %s read-write (%s).  %s has "
					"been opened read-only."),
				dev->path, rw_error_msg, dev->path);
			dev->read_only = 1;
		}
	} else {
		dev->read_only = 0;
	}

	_flush_cache (dev);

	return 1;
}

static int
beos_refresh_open (PedDevice* dev)
{
	return 1;
}

static int
beos_close (PedDevice* dev)
{
	BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev);

	if (dev->dirty)
		_flush_cache (dev);

	close (arch_specific->fd);

	return 1;
}

static int
beos_refresh_close (PedDevice* dev)
{
	if (dev->dirty)
		_flush_cache (dev);

	return 1;
}

static int
beos_read (const PedDevice* dev, void* buffer, PedSector start, PedSector count)
{
	BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev);
	int status;
	PedExceptionOption ex_status;
	size_t read_length = count * dev->sector_size;

	PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, return 0);

	/* First, try to seek */
	while(1)
	{
		if (lseek(arch_specific->fd, start * dev->sector_size, SEEK_SET)
			== start * dev->sector_size)
			break;

		ex_status = ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_RETRY_IGNORE_CANCEL,
			_("%s during seek for read on %s"),
			strerror (errno), dev->path);

		switch (ex_status)
		{
			case PED_EXCEPTION_IGNORE:
				return 1;
			case PED_EXCEPTION_RETRY:
				break /* out of switch */;
			case PED_EXCEPTION_UNHANDLED:
				ped_exception_catch ();
			case PED_EXCEPTION_CANCEL:
				return 0;
		}
	}
	
	/* If we seeked ok, now is the time to read */
	while (1)
	{
		status = read(arch_specific->fd, buffer, read_length);
		if (status == count * dev->sector_size)
			break;
		
		if (status > 0)
		{
			read_length -= status;
			buffer += status;
			continue;
		}

		ex_status = ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_RETRY_IGNORE_CANCEL,
			_("%s during read on %s"),
			strerror (errno),
			dev->path);

		switch (ex_status)
		{
			case PED_EXCEPTION_IGNORE:
				return 1;
			case PED_EXCEPTION_RETRY:
				break;
			case PED_EXCEPTION_UNHANDLED:
				ped_exception_catch ();
			case PED_EXCEPTION_CANCEL:
				return 0;
		}
	}

	return 1;
}

static int
beos_write (PedDevice* dev, const void* buffer, PedSector start,
	PedSector count)
{
	BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev);
	int                     status;
	PedExceptionOption      ex_status;
	size_t                  write_length = count * dev->sector_size;

	PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, return 0);

	if (dev->read_only)
	{
		if (ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("Can't write to %s, because it is opened read-only."),
			dev->path)
			!= PED_EXCEPTION_IGNORE)
			return 0;
		else
			return 1;
	}

	while(1)
	{
		if (lseek(arch_specific->fd,start * dev->sector_size,SEEK_SET)
			== start * dev->sector_size)
			break;

		ex_status = ped_exception_throw (
			PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL,
			_("%s during seek for write on %s"),
			strerror (errno), dev->path);

		switch (ex_status)
		{
			case PED_EXCEPTION_IGNORE:
				return 1;
			case PED_EXCEPTION_RETRY:
				break;
			case PED_EXCEPTION_UNHANDLED:
				ped_exception_catch ();
			case PED_EXCEPTION_CANCEL:
				return 0;
		}
	}

#ifdef READ_ONLY
	printf ("ped_device_write (\"%s\", %p, %d, %d)\n",
		dev->path, buffer, (int) start, (int) count);
#else
	dev->dirty = 1;
	while(1)
	{
		status = write (arch_specific->fd, buffer, write_length);
		if (status == count * dev->sector_size)
			break;
		
		if (status > 0)
		{
			write_length -= status;
			buffer += status;
			continue;
		}

		ex_status = ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_RETRY_IGNORE_CANCEL,
			_("%s during write on %s"),
			strerror (errno), dev->path);

		switch (ex_status)
		{
			case PED_EXCEPTION_IGNORE:
				return 1;
			case PED_EXCEPTION_RETRY:
				break;
			case PED_EXCEPTION_UNHANDLED:
				ped_exception_catch ();
			case PED_EXCEPTION_CANCEL:
				return 0;
		}
	}
#endif /* !READ_ONLY */
	
	return 1;
}

static PedSector
beos_check (PedDevice* dev, void* buffer, PedSector start, PedSector count)
{
	BEOSSpecific*	arch_specific = BEOS_SPECIFIC(dev);
	PedSector		done = 0;
	int				status;

	PED_ASSERT(dev != NULL, return 0);
        
	if (lseek(arch_specific->fd, start * dev->sector_size, SEEK_SET)
		!= start * dev->sector_size)
		return 0;

	for (done = 0; done < count; done += status / dev->sector_size)
	{
		status = read (arch_specific->fd, buffer,
                               (size_t) ((count-done) * dev->sector_size));
		if (status < 0)
			break;
	}

	return done;
}

static int
beos_sync (PedDevice* dev)
{
	return 1;
}

static int
beos_sync_fast (PedDevice* dev)
{
	return 1;
}

/* Probe for all available disks */
static void
beos_probe_all ()
{
	/* For BeOS/ZETA/Haiku, all disks are published under /dev/disk */
	_scan_for_disks("/dev/disk");
}

static char*
beos_partition_get_path (const PedPartition* part)
{
	return NULL;
}

static int
beos_partition_is_busy (const PedPartition* part)
{
	return 0;
}

static int
beos_disk_commit (PedDisk* disk)
{
	return 0;
}

static PedDeviceArchOps beos_dev_ops = {
        _new:           beos_new,
        destroy:        beos_destroy,
        is_busy:        beos_is_busy,
        open:           beos_open,
        refresh_open:   beos_refresh_open,
        close:          beos_close,
        refresh_close:  beos_refresh_close,
        read:           beos_read,
        write:          beos_write,
        check:          beos_check,
        sync:           beos_sync,
        sync_fast:      beos_sync_fast,
        probe_all:      beos_probe_all
};

static PedDiskArchOps beos_disk_ops =  {
        partition_get_path:     beos_partition_get_path,
        partition_is_busy:      beos_partition_is_busy,
        disk_commit:            beos_disk_commit
};

PedArchitecture ped_beos_arch = {
        dev_ops:        &beos_dev_ops,
        disk_ops:       &beos_disk_ops
};
