/*
 * ramfs.c - a malloc based filesystem
 *
 * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * 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
 */

#include <common.h>
#include <driver.h>
#include <init.h>
#include <malloc.h>
#include <fs.h>
#include <command.h>
#include <errno.h>
#include <linux/stat.h>
#include <linux/ctype.h>
#include <xfuncs.h>
#include <fcntl.h>
#include "ff.h"
#include "integer.h"
#include "diskio.h"

struct fat_priv {
	struct cdev *cdev;
	FATFS fat;
};

/* ---------------------------------------------------------------*/

DRESULT disk_read(FATFS *fat, BYTE *buf, DWORD sector, BYTE count)
{
	struct fat_priv *priv = fat->userdata;
	int ret;

	debug("%s: sector: %ld count: %d\n", __func__, sector, count);

	ret = cdev_read(priv->cdev, buf, count << 9, sector * 512, 0);
	if (ret != count << 9)
		return ret;

	return 0;
}

DRESULT disk_write(FATFS *fat, const BYTE *buf, DWORD sector, BYTE count)
{
	struct fat_priv *priv = fat->userdata;
	int ret;

	debug("%s: buf: %p sector: %ld count: %d\n",
			__func__, buf, sector, count);

	ret = cdev_write(priv->cdev, buf, count << 9, sector * 512, 0);
	if (ret != count << 9)
		return ret;

	return 0;
}

DSTATUS disk_status(FATFS *fat)
{
	return 0;
}

DWORD get_fattime(void)
{
	return 0;
}

DRESULT disk_ioctl (FATFS *fat, BYTE command, void *buf)
{
	return 0;
}

WCHAR ff_convert(WCHAR src, UINT dir)
{
	if (src <= 0x80)
		return src;
	else
		return '?';
}

WCHAR ff_wtoupper(WCHAR chr)
{
	if (chr <= 0x80)
		return toupper(chr);
	else
		return '?';
}

/* ---------------------------------------------------------------*/

#ifdef CONFIG_FS_FAT_WRITE
static int fat_create(struct device_d *dev, const char *pathname, mode_t mode)
{
	struct fat_priv *priv = dev->priv;
	FIL f_file;
	int ret;

	ret = f_open(&priv->fat, &f_file, pathname, FA_OPEN_ALWAYS);
	if (ret)
		return -EINVAL;

	f_close(&f_file);

	return 0;
}

static int fat_unlink(struct device_d *dev, const char *pathname)
{
	struct fat_priv *priv = dev->priv;
	int ret;

	ret = f_unlink(&priv->fat, pathname);
	if (ret)
		return ret;

	cdev_flush(priv->cdev);

	return 0;
}

static int fat_mkdir(struct device_d *dev, const char *pathname)
{
	struct fat_priv *priv = dev->priv;
	int ret;

	ret = f_mkdir(&priv->fat, pathname);
	if (ret)
		return ret;

	cdev_flush(priv->cdev);

	return 0;
}

static int fat_rmdir(struct device_d *dev, const char *pathname)
{
	struct fat_priv *priv = dev->priv;
	int ret;

	ret = f_unlink(&priv->fat, pathname);
	if (ret)
		return ret;

	cdev_flush(priv->cdev);

	return 0;
}

static int fat_write(struct device_d *_dev, FILE *f, const void *buf, size_t insize)
{
	FIL *f_file = f->inode;
	int outsize;
	int ret;

	ret = f_write(f_file, buf, insize, &outsize);

	debug("%s: %d %d %d %p\n", __func__, ret, insize, outsize, f_file);

	if (ret)
		return ret;
	if (!outsize)
		return -ENOSPC;

	return outsize;
}

static int fat_truncate(struct device_d *dev, FILE *f, ulong size)
{
	FIL *f_file = f->inode;
	unsigned long lastofs;
	int ret;

	lastofs = f_file->fptr;

	ret = f_lseek(f_file, size);
	if (ret)
		return ret;

	ret = f_truncate(f_file);
	if (ret)
		return ret;

	ret = f_lseek(f_file, lastofs);
	if (ret)
		return ret;

	return 0;
}
#endif /* CONFIG_FS_FAT_WRITE */

static int fat_open(struct device_d *dev, FILE *file, const char *filename)
{
	struct fat_priv *priv = dev->priv;
	FIL *f_file;
	int ret;
	unsigned long flags = 0;

	f_file = xzalloc(sizeof(*f_file));

	switch (file->flags & O_ACCMODE) {
	case O_RDONLY:
		flags = FA_READ;
		break;
	case O_WRONLY:
		flags = FA_WRITE;
		break;
	case O_RDWR:
		flags = FA_READ | FA_WRITE;
		break;
	}

	ret = f_open(&priv->fat, f_file, filename, flags);
	if (ret) {
		free(f_file);
		return -EINVAL;
	}

	if (file->flags & O_APPEND) {
		ret = f_lseek(f_file, f_file->fsize);
	}

	file->inode = f_file;
	file->size = f_file->fsize;

	return 0;
}

static int fat_close(struct device_d *dev, FILE *f)
{
	struct fat_priv *priv = dev->priv;
	FIL *f_file = f->inode;

	f_close(f_file);

	free(f_file);

	cdev_flush(priv->cdev);

	return 0;
}

static int fat_read(struct device_d *_dev, FILE *f, void *buf, size_t insize)
{
	int ret;
	FIL *f_file = f->inode;
	int outsize;

	ret = f_read(f_file, buf, insize, &outsize);

	debug("%s: %d %d %d %p\n", __func__, ret, insize, outsize, f_file);

	if (ret)
		return ret;

	return outsize;
}

static off_t fat_lseek(struct device_d *dev, FILE *f, off_t pos)
{
	FIL *f_file = f->inode;
	int ret;

	ret = f_lseek(f_file, pos);
	if (ret)
		return ret;

	return pos;
}

static DIR* fat_opendir(struct device_d *dev, const char *pathname)
{
	struct fat_priv *priv = dev->priv;
	DIR *dir;
	FF_DIR *ff_dir;
	int ret;

	debug("%s: %s\n", __func__, pathname);

	ff_dir = xzalloc(sizeof(*ff_dir));
	if (pathname)
		ret = f_opendir(&priv->fat, ff_dir, pathname);
	else
		ret = f_opendir(&priv->fat, ff_dir, "/");

	if (ret)
		return NULL;

	dir = xzalloc(sizeof(*dir));

	dir->priv = ff_dir;

	return dir;
}

static struct dirent* fat_readdir(struct device_d *dev, DIR *dir)
{
	FF_DIR *ff_dir = dir->priv;
	FILINFO finfo;
	int ret;
#ifdef CONFIG_FS_FAT_LFN
	char name[PATH_MAX];
#endif
	memset(&finfo, 0, sizeof(finfo));
#ifdef CONFIG_FS_FAT_LFN
	finfo.lfname = name;
	finfo.lfsize = PATH_MAX;
#endif
	ret = f_readdir(ff_dir, &finfo);
	if (ret)
		return NULL;

	if (finfo.fname[0] == '\0')
		return NULL;

#ifdef CONFIG_FS_FAT_LFN
	if (*finfo.lfname)
		strcpy(dir->d.d_name, finfo.lfname);
	else
#endif
		strcpy(dir->d.d_name, finfo.fname);

	return &dir->d;
}

static int fat_closedir(struct device_d *dev, DIR *dir)
{
	FF_DIR *ff_dir = dir->priv;

	free(ff_dir);
	free(dir);

	return 0;
}

static int fat_stat(struct device_d *dev, const char *filename, struct stat *s)
{
	struct fat_priv *priv = dev->priv;
	FILINFO finfo;
	int ret;

	ret = f_stat(&priv->fat, filename, &finfo);
	if (ret)
		return ret;

	s->st_size = finfo.fsize;
	s->st_mode = S_IRWXU | S_IRWXG | S_IRWXO;

	if (finfo.fattrib & AM_DIR)
		s->st_mode |= S_IFDIR;
	else
		s->st_mode |= S_IFREG;

	return 0;
}

static int fat_probe(struct device_d *dev)
{
	struct fs_device_d *fsdev = dev->type_data;
	struct fat_priv *priv = xzalloc(sizeof(struct fat_priv));
	char *backingstore = fsdev->backingstore;

	dev->priv = priv;

	if (!strncmp(backingstore , "/dev/", 5))
		backingstore += 5;

	priv->cdev = cdev_open(backingstore, O_RDWR);
	if (!priv->cdev)
		return -EINVAL;

	priv->fat.userdata = priv;
	f_mount(&priv->fat);

	return 0;
}

static void fat_remove(struct device_d *dev)
{
	struct fat_priv *priv = dev->priv;

	cdev_close(priv->cdev);

	free(dev->priv);
}

static struct fs_driver_d fat_driver = {
	.open      = fat_open,
	.close     = fat_close,
	.read      = fat_read,
	.lseek     = fat_lseek,
	.opendir   = fat_opendir,
	.readdir   = fat_readdir,
	.closedir  = fat_closedir,
	.stat      = fat_stat,
#ifdef CONFIG_FS_FAT_WRITE
	.create    = fat_create,
	.unlink    = fat_unlink,
	.mkdir     = fat_mkdir,
	.rmdir     = fat_rmdir,
	.write     = fat_write,
	.truncate  = fat_truncate,
#endif
	.flags     = 0,
	.drv = {
		.probe  = fat_probe,
		.remove = fat_remove,
		.name = "fat",
		.type_data = &fat_driver,
	}
};

static int fat_init(void)
{
	return register_fs_driver(&fat_driver);
}

coredevice_initcall(fat_init);

