/* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-

    libparted - a library for manipulating disk partitions
    Copyright (C) 2000, 2001, 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Contributor:  Matt Wilson <msw@redhat.com>
*/

#include <config.h>

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

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

#define	AIX_LABEL_MAGIC		0xc9c2d4c1

static PedDiskType aix_disk_type;

static inline int
aix_label_magic_get (const char *label)
{
	return *(unsigned int *)label;
}

static inline void
aix_label_magic_set (char *label, int magic_val)
{
	*(unsigned int *)label = magic_val;
}

/* Read a single sector, of length DEV->sector_size, into malloc'd storage.
   If the read fails, free the memory and return zero without modifying *BUF.
   Otherwise, set *BUF to the new buffer and return 1.  */
static int
read_sector (const PedDevice *dev, char **buf)
{
	char *b = ped_malloc (dev->sector_size);
	PED_ASSERT (b != NULL, return 0);
	if (!ped_device_read (dev, b, 0, 1)) {
		ped_free (b);
		return 0;
	}
	*buf = b;
	return 1;
}

static int
aix_probe (const PedDevice *dev)
{
	PED_ASSERT (dev != NULL, return 0);

	char *label;
	if (!read_sector (dev, &label))
		return 0;
	unsigned int magic = aix_label_magic_get (label);
	ped_free (label);
	return magic == AIX_LABEL_MAGIC;
}

#ifndef DISCOVER_ONLY
static int
aix_clobber (PedDevice* dev)
{
	PED_ASSERT (dev != NULL, return 0);

	if (!aix_probe (dev))
		return 0;

	char *label;
	if (!read_sector (dev, &label))
		return 0;

	aix_label_magic_set (label, 0);
	int result = ped_device_write (dev, label, 0, 1);
	ped_free (label);
	return result;
}
#endif /* !DISCOVER_ONLY */

static PedDisk*
aix_alloc (const PedDevice* dev)
{
	PedDisk*	disk;

        disk = _ped_disk_alloc (dev, &aix_disk_type);
	if (!disk)
		return NULL;

	return disk;
}

static PedDisk*
aix_duplicate (const PedDisk* disk)
{
	PedDisk*	new_disk;
       
	new_disk = ped_disk_new_fresh (disk->dev, &aix_disk_type);
	if (!new_disk)
		return NULL;

	return new_disk;
}

static void
aix_free (PedDisk *disk)
{
	_ped_disk_free (disk);
}

static int
aix_read (PedDisk* disk)
{
	ped_disk_delete_all (disk);
        ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
                             PED_EXCEPTION_CANCEL,
                             _("Support for reading AIX disk labels is "
                               "is not implemented yet."));
        return 0;
}

#ifndef DISCOVER_ONLY
static int
aix_write (const PedDisk* disk)
{
        ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
                             PED_EXCEPTION_CANCEL,
                             _("Support for writing AIX disk labels is "
                               "is not implemented yet."));
	return 0;
}
#endif /* !DISCOVER_ONLY */

static PedPartition*
aix_partition_new (const PedDisk* disk, PedPartitionType part_type,
		   const PedFileSystemType* fs_type,
		   PedSector start, PedSector end)
{
        ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
                             PED_EXCEPTION_CANCEL,
                             _("Support for adding partitions to AIX disk "
                               "labels is not implemented yet."));
        return NULL;
}

static PedPartition*
aix_partition_duplicate (const PedPartition* part)
{
        ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
                             PED_EXCEPTION_CANCEL,
                             _("Support for duplicating partitions in AIX "
                               "disk labels is not implemented yet."));
        return NULL;
}

static void
aix_partition_destroy (PedPartition* part)
{
	PED_ASSERT (part != NULL, return);

	_ped_partition_free (part);
}

static int
aix_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
{
        ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
                             PED_EXCEPTION_CANCEL,
                             _("Support for setting system type of partitions "
                               "in AIX disk labels is not implemented yet."));
	return 0;
}

static int
aix_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
{
        ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
                             PED_EXCEPTION_CANCEL,
                             _("Support for setting flags "
                               "in AIX disk labels is not implemented yet."));
        return 0;
}

static int
aix_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
{
        return 0;
}


static int
aix_partition_is_flag_available (const PedPartition* part,
				 PedPartitionFlag flag)
{
        return 0;
}


static int
aix_get_max_primary_partition_count (const PedDisk* disk)
{
	return 4;
}

static int
aix_partition_align (PedPartition* part, const PedConstraint* constraint)
{
        PED_ASSERT (part != NULL, return 0);

        return 1;
}

static int
aix_partition_enumerate (PedPartition* part)
{
	return 1;
}

static int
aix_alloc_metadata (PedDisk* disk)
{
	return 1;
}

static PedDiskOps aix_disk_ops = {
	probe:			aix_probe,
#ifndef DISCOVER_ONLY
	clobber:		aix_clobber,
#else
	clobber:		NULL,
#endif
	alloc:			aix_alloc,
	duplicate:		aix_duplicate,
	free:			aix_free,
	read:			aix_read,
#ifndef DISCOVER_ONLY
	write:			aix_write,
#else
	write:			NULL,
#endif

	partition_new:		aix_partition_new,
	partition_duplicate:	aix_partition_duplicate,
	partition_destroy:	aix_partition_destroy,
	partition_set_system:	aix_partition_set_system,
	partition_set_flag:	aix_partition_set_flag,
	partition_get_flag:	aix_partition_get_flag,
	partition_is_flag_available:	aix_partition_is_flag_available,
	partition_align:	aix_partition_align,
	partition_enumerate:	aix_partition_enumerate,
	alloc_metadata:		aix_alloc_metadata,
	get_max_primary_partition_count:
				aix_get_max_primary_partition_count,

	partition_set_name:		NULL,
	partition_get_name:		NULL,
};

static PedDiskType aix_disk_type = {
	next:		NULL,
	name:		"aix",
	ops:		&aix_disk_ops,
	features:	0
};

void
ped_disk_aix_init ()
{
	ped_disk_type_register (&aix_disk_type);
}

void
ped_disk_aix_done ()
{
	ped_disk_type_unregister (&aix_disk_type);
}
