/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *		http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "MtpStorage"

#include "MtpDebug.h"
#include "MtpStorage.h"
#include "btree.hpp"

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include <iterator>
#include <sys/inotify.h>

#define WATCH_FLAGS ( IN_CREATE | IN_DELETE | IN_MOVE | IN_MODIFY )

MtpStorage::MtpStorage(MtpStorageID id, const char* filePath,
		const char* description, bool removable, uint64_t maxFileSize, MtpServer* refserver)
	:	mStorageID(id),
		mFilePath(filePath),
		mDescription(description),
		mMaxCapacity(0),
		mMaxFileSize(maxFileSize),
		mRemovable(removable),
	mServer(refserver)
{
	MTPD("MtpStorage id: %d path: %s\n", id, filePath);
	inotify_thread = 0;
	inotify_fd = -1;
	// Threading has not started yet so we should be safe to set these directly instead of using atomics
	inotify_thread_kill.set_value(0);
	sendEvents = false;
	handleCurrentlySending = 0;
	use_mutex = true;
	if (pthread_mutex_init(&mtpMutex, NULL) != 0) {
			MTPE("Failed to init mtpMutex\n");
			use_mutex = false;
	}
	if (pthread_mutex_init(&inMutex, NULL) != 0) {
			MTPE("Failed to init inMutex\n");
			pthread_mutex_destroy(&mtpMutex);
			use_mutex = false;
	}
}

MtpStorage::~MtpStorage() {
	if (inotify_thread) {
			inotify_thread_kill.set_value(1);
			MTPD("joining inotify_thread after sending the kill notification.\n");
			pthread_join(inotify_thread, NULL); // There's not much we can do if there's an error here
			inotify_thread = 0;
			MTPD("~MtpStorage removing inotify watches and closing inotify_fd\n");
			for (std::map<int, Tree*>::iterator i = inotifymap.begin(); i != inotifymap.end(); i++) {
					inotify_rm_watch(inotify_fd, i->first);
			}
			close(inotify_fd);
			inotifymap.clear();
	}
		// Deleting the root tree causes a cascade in btree.cpp that ends up
		// deleting all of the trees and nodes.
		delete mtpmap[0];
		mtpmap.clear();
		if (use_mutex) {
				use_mutex = false;
				MTPD("~MtpStorage destroying mutexes\n");
				pthread_mutex_destroy(&mtpMutex);
				pthread_mutex_destroy(&inMutex);
		}

}

int MtpStorage::getType() const {
	return (mRemovable ? MTP_STORAGE_REMOVABLE_RAM :  MTP_STORAGE_FIXED_RAM);
}

int MtpStorage::getFileSystemType() const {
	return MTP_STORAGE_FILESYSTEM_HIERARCHICAL;
}

int MtpStorage::getAccessCapability() const {
	return MTP_STORAGE_READ_WRITE;
}

uint64_t MtpStorage::getMaxCapacity() {
	if (mMaxCapacity == 0) {
		struct statfs	stat;
		if (statfs(getPath(), &stat))
			return -1;
		mMaxCapacity = (uint64_t)stat.f_blocks * (uint64_t)stat.f_bsize;
	}
	return mMaxCapacity;
}

uint64_t MtpStorage::getFreeSpace() {
	struct statfs	stat;
	if (statfs(getPath(), &stat))
		return -1;
	return (uint64_t)stat.f_bavail * (uint64_t)stat.f_bsize;
}

const char* MtpStorage::getDescription() const {
	return (const char *)mDescription;
}

int MtpStorage::renameObject(MtpObjectHandle handle, std::string newName) {
		MTPD("MtpStorage::renameObject, handle: %u, new name: '%s'\n", handle, newName.c_str());
		if (handle == MTP_PARENT_ROOT) {
				MTPE("parent == MTP_PARENT_ROOT, cannot rename root\n");
				return -1;
		} else {
				for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
						Node* node = i->second->findNode(handle);
						if (node != NULL) {
				std::string oldName = getNodePath(node);
								std::string parentdir = oldName.substr(0, oldName.find_last_of('/'));
								std::string newFullName = parentdir + "/" + newName;
								MTPD("old: '%s', new: '%s'\n", oldName.c_str(), newFullName.c_str());
								if (rename(oldName.c_str(), newFullName.c_str()) == 0) {
										node->rename(newName);
										return 0;
								} else {
										MTPE("MtpStorage::renameObject failed, handle: %u, new name: '%s'\n", handle, newName.c_str());
										return -1;
								}
						}
				}
		}
		// handle not found on this storage
		return -1;
}

MtpObjectHandle MtpStorage::beginSendObject(const char* path,
																						MtpObjectFormat format,
																						MtpObjectHandle parent,
																						__attribute__((unused)) uint64_t size,
																						__attribute__((unused)) time_t modified) {
		MTPD("MtpStorage::beginSendObject(), path: '%s', parent: %u, format: %04x\n", path, parent, format);
		iter it = mtpmap.find(parent);
		if (it == mtpmap.end()) {
				MTPE("parent node not found, returning error\n");
				return kInvalidObjectHandle;
		}
		Tree* tree = it->second;

		std::string pathstr(path);
		size_t slashpos = pathstr.find_last_of('/');
		if (slashpos == std::string::npos) {
				MTPE("path has no slash, returning error\n");
				return kInvalidObjectHandle;
		}
		std::string parentdir = pathstr.substr(0, slashpos);
		std::string basename = pathstr.substr(slashpos + 1);
		if (parent != 0 && parentdir != getNodePath(tree)) {
				MTPE("beginSendObject into path '%s' but parent tree has path '%s', returning error\n", parentdir.c_str(), getNodePath(tree).c_str());
				return kInvalidObjectHandle;
		}

		MTPD("MtpStorage::beginSendObject() parentdir: %s basename: %s\n", parentdir.c_str(), basename.c_str());
		// note: for directories, the mkdir call is done later in MtpServer, here we just reserve a handle
		bool isDir = format == MTP_FORMAT_ASSOCIATION;
		Node* node = addNewNode(isDir, tree, basename);
		handleCurrentlySending = node->Mtpid(); // suppress inotify for this node while sending

		return node->Mtpid();
}

int MtpStorage::createDB() {
		std::string mtpParent = "";
		mtpstorageparent = getPath();
		// root directory is special: handle 0, parent 0, and empty path
		mtpmap[0] = new Tree(0, 0, "");
		if (use_mutex) {
				sendEvents = true;
				MTPD("inotify_init\n");
				inotify_fd = inotify_init();
				if (inotify_fd < 0) {
						MTPE("Can't run inotify_init for mtp server: %s\n", strerror(errno));
				} else {
						MTPD("Starting inotify thread\n");
						inotify_thread = inotify();
				}
		} else {
				MTPD("NOT starting inotify thread\n");
		}
		// for debugging and caching purposes, read the root dir already now
		readDir(mtpstorageparent, mtpmap[0]);
		// all other dirs are read on demand
	//
		MTPD("MtpStorage::createDB DONE\n");
		return 0;
}

Node* MtpStorage::findNode(MtpObjectHandle handle) {
		for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
				Node* node = i->second->findNode(handle);
				if (node != NULL) {
						MTPD("findNode: found node %p for handle %u, name: %s\n", node, handle, node->getName().c_str());
						if (node->Mtpid() != handle)
						{
								MTPE("BUG: entry for handle %u points to node with handle %u\n", handle, node->Mtpid());
						}
						return node;
				}
		}
		// Item is not on this storage device
		MTPD("MtpStorage::findNode: no node found for handle %u on storage %u, searched %u trees\n", handle, mStorageID, mtpmap.size());
		return NULL;
}

std::string MtpStorage::getNodePath(Node* node) {
	std::string path;
		MTPD("getNodePath: node %p, handle %u\n", node, node->Mtpid());
		while (node)
		{
				path = "/" + node->getName() + path;
				MtpObjectHandle parent = node->getMtpParentId();
				if (parent == 0)		// root
						break;
				node = findNode(parent);
		}
		path = mtpstorageparent + path;
		MTPD("getNodePath: path %s\n", path.c_str());
		return path;
}

MtpObjectHandleList* MtpStorage::getObjectList(__attribute__((unused)) MtpStorageID storageID, MtpObjectHandle parent) {
		MTPD("MtpStorage::getObjectList, parent: %u\n", parent);
		//append object id	(numerical #s) of database to int array
		MtpObjectHandleList* list = new MtpObjectHandleList();
		if (parent == MTP_PARENT_ROOT) {
				MTPD("parent == MTP_PARENT_ROOT\n");
				parent = 0;
		}

		if (mtpmap.find(parent) == mtpmap.end()) {
				MTPE("parent handle not found, returning empty list\n");
				return list;
		}

		Tree* tree = mtpmap[parent];
		if (!tree->wasAlreadyRead())
		{
				std::string path = getNodePath(tree);
				MTPD("reading directory on demand for tree %p (%u), path: %s\n", tree, tree->Mtpid(), path.c_str());
				readDir(path, tree);
		}

		mtpmap[parent]->getmtpids(list);
		MTPD("returning %u objects in %s.\n", list->size(), tree->getName().c_str());
		return list;
}

Node* MtpStorage::addNewNode(bool isDir, Tree* tree, const std::string& name)
{
		// global counter for new object handles
		static MtpObjectHandle mtpid = 0;

		++mtpid;
		MTPD("adding new %s node for %s, new handle: %u\n", isDir ? "dir" : "file", name.c_str(), mtpid);
		MtpObjectHandle parent = tree->Mtpid();
		MTPD("parent tree: %x, handle: %u, name: %s\n", tree, parent, tree->getName().c_str());
		Node* node;
		if (isDir)
				node = mtpmap[mtpid] = new Tree(mtpid, parent, name);
		else
				node = new Node(mtpid, parent, name);
		tree->addEntry(node);
		return node;
}

int MtpStorage::readDir(const std::string& path, Tree* tree)
{
		struct dirent *de;
		int storageID = getStorageID();
		MtpObjectHandle parent = tree->Mtpid();

		DIR *d = opendir(path.c_str());
		MTPD("reading dir '%s', parent handle %u\n", path.c_str(), parent);
		if (d == NULL) {
				MTPE("error opening '%s' -- error: %s\n", path.c_str(), strerror(errno));
				return -1;
		}
		// TODO: for refreshing dirs: capture old entries here
		while ((de = readdir(d)) != NULL) {
				// Because exfat-fuse causes issues with dirent, we will use stat
				// for some things that dirent should be able to do
				std::string item = path + "/" + de->d_name;
				struct stat st;
				if (lstat(item.c_str(), &st)) {
						MTPE("Error running lstat on '%s'\n", item.c_str());
						return -1;
				}
				// TODO: if we want to use this for refreshing dirs too, first find existing name and overwrite
				if (strcmp(de->d_name, ".") == 0)
						continue;
				if (strcmp(de->d_name, "..") == 0)
						continue;
				Node* node = addNewNode(st.st_mode & S_IFDIR, tree, de->d_name);
				node->addProperties(item, storageID);
				//if (sendEvents)
				//		mServer->sendObjectAdded(node->Mtpid());
				//		sending events here makes simple-mtpfs very slow, and it is probably the wrong thing to do anyway
		}
		closedir(d);
		// TODO: for refreshing dirs: remove entries that no longer exist (with their nodes)
		tree->setAlreadyRead(true);
		addInotify(tree);
		return 0;
}

int MtpStorage::addInotify(Tree* tree) {
		if (inotify_fd < 0) {
				MTPE("inotify_fd not set or error: %i\n", inotify_fd);
				return -1;
		}
		std::string path = getNodePath(tree);
		MTPD("adding inotify for tree %x, dir: %s\n", tree, path.c_str());
		int wd = inotify_add_watch(inotify_fd, path.c_str(), WATCH_FLAGS);
		if (wd < 0) {
				MTPE("inotify_add_watch failed: %s\n", strerror(errno));
				return -1;
		}
		inotifymap[wd] = tree;
		return 0;
}

pthread_t MtpStorage::inotify(void) {
		pthread_t thread;
		pthread_attr_t tattr;

		if (pthread_attr_init(&tattr)) {
				MTPE("Unable to pthread_attr_init\n");
				return 0;
		}
		if (pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE)) {
				MTPE("Error setting pthread_attr_setdetachstate\n");
				return 0;
		}
		ThreadPtr inotifyptr = &MtpStorage::inotify_t;
		PThreadPtr p = *(PThreadPtr*)&inotifyptr;
		pthread_create(&thread, &tattr, p, this);
		if (pthread_attr_destroy(&tattr)) {
				MTPE("Failed to pthread_attr_destroy\n");
		}
		return thread;
}

int MtpStorage::inotify_t(void) {
		#define EVENT_SIZE ( sizeof(struct inotify_event) )
		#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16) )
		char buf[EVENT_BUF_LEN];
		fd_set fdset;
		struct timeval seltmout;
		int sel_ret;

		MTPD("inotify thread starting.\n");

		while (inotify_thread_kill.get_value() == 0) {
				FD_ZERO(&fdset);
				FD_SET(inotify_fd, &fdset);
				seltmout.tv_sec = 0;
				seltmout.tv_usec = 25000;
				sel_ret = select(inotify_fd + 1, &fdset, NULL, NULL, &seltmout);
				if (sel_ret == 0)
						continue;
				int i = 0;
				int len = read(inotify_fd, buf, EVENT_BUF_LEN);

				if (len < 0) {
						if (errno == EINTR)
								continue;
						MTPE("inotify_t Can't read inotify events\n");
				}

				while (i < len && inotify_thread_kill.get_value() == 0) {
						struct inotify_event *event = (struct inotify_event *) &buf[i];
						if (event->len) {
								MTPD("inotify event: wd: %i, mask: %x, name: %s\n", event->wd, event->mask, event->name);
								lockMutex(1);
								handleInotifyEvent(event);
								unlockMutex(1);
						}
						i += EVENT_SIZE + event->len;
				}
		}
		MTPD("inotify_thread_kill received!\n");
		// This cleanup is handled in the destructor.
		/*for (std::map<int, Tree*>::iterator i = inotifymap.begin(); i != inotifymap.end(); i++) {
				inotify_rm_watch(inotify_fd, i->first);
		}
		close(inotify_fd);*/
		return 0;
}

void MtpStorage::handleInotifyEvent(struct inotify_event* event)
{
		std::map<int, Tree*>::iterator it = inotifymap.find(event->wd);
		if (it == inotifymap.end()) {
				MTPE("Unable to locate inotify_wd: %i\n", event->wd);
				return;
		}
		Tree* tree = it->second;
		MTPD("inotify_t tree: %x '%s'\n", tree, tree->getName().c_str());
		Node* node = tree->findEntryByName(basename(event->name));
		if (node && node->Mtpid() == handleCurrentlySending) {
				MTPD("ignoring inotify event for currently uploading file, handle: %u\n", node->Mtpid());
				return;
		}
		if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO) {
				if (event->mask & IN_ISDIR) {
						MTPD("inotify_t create is dir\n");
				} else {
						MTPD("inotify_t create is file\n");
				}
				if (node == NULL) {
						node = addNewNode(event->mask & IN_ISDIR, tree, event->name);
						std::string item = getNodePath(tree) + "/" + event->name;
						node->addProperties(item, getStorageID());
						mServer->sendObjectAdded(node->Mtpid());
				} else {
						MTPD("inotify_t item already exists.\n");
				}
				if (event->mask & IN_ISDIR) {
						// TODO: do we need to do anything here? probably not until someone reads from the dir...
				}
		} else if (event->mask & IN_DELETE || event->mask & IN_MOVED_FROM) {
				if (event->mask & IN_ISDIR) {
						MTPD("inotify_t Directory %s deleted\n", event->name);
				} else {
						MTPD("inotify_t File %s deleted\n", event->name);
				}
				if (node)
				{
						if (event->mask & IN_ISDIR) {
								for (std::map<int, Tree*>::iterator it = inotifymap.begin(); it != inotifymap.end(); ++it) {
										if (it->second == node) {
												inotify_rm_watch(inotify_fd, it->first);
												MTPD("inotify_t removing watch on '%s'\n", getNodePath(it->second).c_str());
												inotifymap.erase(it->first);
												break;
										}

								}
						}
						MtpObjectHandle handle = node->Mtpid();
						deleteFile(handle);
						mServer->sendObjectRemoved(handle);
				} else {
						MTPD("inotify_t already removed.\n");
				}
		} else if (event->mask & IN_MODIFY) {
				MTPD("inotify_t item %s modified.\n", event->name);
				if (node != NULL) {
						uint64_t orig_size = node->getProperty(MTP_PROPERTY_OBJECT_SIZE).valueInt;
						struct stat st;
						uint64_t new_size = 0;
						if (lstat(getNodePath(node).c_str(), &st) == 0)
								new_size = (uint64_t)st.st_size;
						if (orig_size != new_size) {
								MTPD("size changed from %llu to %llu on mtpid: %u\n", orig_size, new_size, node->Mtpid());
								node->updateProperty(MTP_PROPERTY_OBJECT_SIZE, new_size, "", MTP_TYPE_UINT64);
								mServer->sendObjectUpdated(node->Mtpid());
						}
				} else {
						MTPE("inotify_t modified item not found\n");
				}
		} else if (event->mask & IN_DELETE_SELF || event->mask & IN_MOVE_SELF) {
				// TODO: is this always already handled by IN_DELETE for the parent dir?
		}
}

void MtpStorage::lockMutex(int thread_type) {
		if (!use_mutex)
				return; // mutex is disabled
		if (thread_type) {
				// inotify thread
				pthread_mutex_lock(&inMutex);
				while (pthread_mutex_trylock(&mtpMutex)) {
						pthread_mutex_unlock(&inMutex);
						usleep(32000);
						pthread_mutex_lock(&inMutex);
				}
		} else {
				// main mtp thread
				pthread_mutex_lock(&mtpMutex);
				while (pthread_mutex_trylock(&inMutex)) {
						pthread_mutex_unlock(&mtpMutex);
						usleep(13000);
						pthread_mutex_lock(&mtpMutex);
				}
		}
}

void MtpStorage::unlockMutex( __attribute__((unused)) int thread_type) {
		if (!use_mutex)
				return; // mutex is disabled
		pthread_mutex_unlock(&inMutex);
		pthread_mutex_unlock(&mtpMutex);
}

int MtpStorage::getObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property, MtpStorage::PropEntry& pe) {
		Node *node;
		for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
				node = i->second->findNode(handle);
				if (node != NULL) {
						const Node::mtpProperty& prop = node->getProperty(property);
						if (prop.property != property) {
								MTPD("getObjectPropertyValue: unknown property %x for handle %u\n", property, handle);
								return -1;
						}
						pe.datatype = prop.dataType;
						pe.intvalue = prop.valueInt;
						pe.strvalue = prop.valueStr;
						pe.handle = handle;
						pe.property = property;
						return 0;
				}
		}
		// handle not found on this storage
		return -1;
}

void MtpStorage::endSendObject(const char* path, MtpObjectHandle handle, __attribute__((unused)) MtpObjectFormat format, __attribute__((unused)) bool succeeded)
{
		Node* node = findNode(handle);
		if (!node)
				return; // just ignore if this is for another storage

		node->addProperties(path, mStorageID);
		handleCurrentlySending = 0;
		// TODO: are we supposed to send an event about an upload by the initiator?
		if (sendEvents)
				mServer->sendObjectAdded(node->Mtpid());
}

int MtpStorage::getObjectPropertyList(MtpObjectHandle handle, uint32_t format, uint32_t property, int groupCode, __attribute__((unused)) int depth, MtpDataPacket& packet) {
		MTPD("MtpStorage::getObjectPropertyList handle: %u, format: %x, property: %x\n", handle, format, property);
		if (groupCode != 0)
		{
				MTPE("getObjectPropertyList: groupCode unsupported\n");
				return -1; // TODO: RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED
		}
		// TODO: support all the special stuff, like:
		// handle == 0 -> all objects at the root level
		// handle == 0xffffffff -> all objects (on all storages? how could we support that?)
		// format == 0 -> all formats, otherwise filter by ObjectFormatCode
		// property == 0xffffffff -> all properties except those with group code 0xffffffff
		// if property == 0 then use groupCode
		//	 groupCode == 0 -> return Specification_By_Group_Unsupported
		// depth == 0xffffffff -> all objects incl. and below handle

		std::vector<PropEntry> results;

		if (handle == 0xffffffff) {
				// TODO: all object on all storages (needs a different design, result packet needs to be built by server instead of storage)
		} else if (handle == 0) {
				// all objects at the root level
				Tree* root = mtpmap[0];
				MtpObjectHandleList list;
				root->getmtpids(&list);
				for (MtpObjectHandleList::iterator it = list.begin(); it != list.end(); ++it) {
						Node* node = root->findNode(*it);
						if (!node) {
								MTPE("BUG: node not found for root entry with handle %u\n", *it);
								break;
						}
						queryNodeProperties(results, node, property, groupCode, mStorageID);
				}
		} else {
				// single object
				Node* node = findNode(handle);
				if (!node) {
						// Item is not on this storage device
						return -1;
				}
				queryNodeProperties(results, node, property, groupCode, mStorageID);
		}

		MTPD("MtpStorage::getObjectPropertyList::count: %u\n", results.size());
		packet.putUInt32(results.size());

		for (size_t i = 0; i < results.size(); ++i) {
				PropEntry& p = results[i];
				MTPD("handle: %u, propertyCode: %x = %s, datatype: %x, value: %llu\n",
								p.handle, p.property, MtpDebug::getObjectPropCodeName(p.property),
								p.datatype, p.intvalue);
				packet.putUInt32(p.handle);
				packet.putUInt16(p.property);
				packet.putUInt16(p.datatype);
				switch (p.datatype) {
						case MTP_TYPE_INT8:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_INT8\n");
								packet.putInt8(p.intvalue);
								break;
						case MTP_TYPE_UINT8:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_UINT8\n");
								packet.putUInt8(p.intvalue);
								break;
						case MTP_TYPE_INT16:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_INT16\n");
								packet.putInt16(p.intvalue);
								break;
						case MTP_TYPE_UINT16:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_UINT16\n");
								packet.putUInt16(p.intvalue);
								break;
						case MTP_TYPE_INT32:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_INT32\n");
								packet.putInt32(p.intvalue);
								break;
						case MTP_TYPE_UINT32:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_UINT32\n");
								packet.putUInt32(p.intvalue);
								break;
						case MTP_TYPE_INT64:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_INT64\n");
								packet.putInt64(p.intvalue);
								break;
						case MTP_TYPE_UINT64:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_UINT64\n");
								packet.putUInt64(p.intvalue);
								break;
						case MTP_TYPE_INT128:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_INT128\n");
								packet.putInt128(p.intvalue);
								break;
						case MTP_TYPE_UINT128:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_UINT128\n");
								packet.putUInt128(p.intvalue);
								break;
						case MTP_TYPE_STR:
								MTPD("MtpStorage::getObjectPropertyList::MTP_TYPE_STR: %s\n", p.strvalue.c_str());
								packet.putString(p.strvalue.c_str());
								break;
						default:
								MTPE("bad or unsupported data type: %x in MyMtpDatabase::getObjectPropertyList", p.datatype);
								break;
				}
		}
		return 0;
}

int MtpStorage::getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info) {
		struct stat st;
		uint64_t size = 0;
		MTPD("MtpStorage::getObjectInfo, handle: %u\n", handle);
		Node* node = findNode(handle);
		if (!node) {
				// Item is not on this storage device
				return -1;
		}

		info.mStorageID = getStorageID();
		MTPD("info.mStorageID: %u\n", info.mStorageID);
		info.mParent = node->getMtpParentId();
		MTPD("mParent: %u\n", info.mParent);
		// TODO: do we want to lstat again here, or read from the node properties?
		if (lstat(getNodePath(node).c_str(), &st) == 0)
				size = st.st_size;
		MTPD("size is: %llu\n", size);
		info.mCompressedSize = (size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size);
		info.mDateModified = st.st_mtime;
		if (S_ISDIR(st.st_mode)) {
				info.mFormat = MTP_FORMAT_ASSOCIATION;
		}
		else {
				info.mFormat = MTP_FORMAT_UNDEFINED;
		}
		info.mName = strdup(node->getName().c_str());
		MTPD("MtpStorage::getObjectInfo found, Exiting getObjectInfo()\n");
		return 0;
}

int MtpStorage::getObjectFilePath(MtpObjectHandle handle, MtpStringBuffer& outFilePath, int64_t& outFileLength, MtpObjectFormat& outFormat) {
		MTPD("MtpStorage::getObjectFilePath handle: %u\n", handle);
		Node* node = findNode(handle);
		if (!node)
		{
				// Item is not on this storage device
				return -1;
		}
		// TODO: do we want to lstat here, or just read the info from the node?
		struct stat st;
		if (lstat(getNodePath(node).c_str(), &st) == 0)
				outFileLength = st.st_size;
		else
				outFileLength = 0;
		outFilePath.set(getNodePath(node).c_str());
		MTPD("outFilePath: %s\n", (const char*) outFilePath);
		outFormat = node->isDir() ? MTP_FORMAT_ASSOCIATION : MTP_FORMAT_UNDEFINED;
		return 0;
}

int MtpStorage::deleteFile(MtpObjectHandle handle) {
		MTPD("MtpStorage::deleteFile handle: %u\n", handle);
		Node* node = findNode(handle);
		if (!node) {
				// Item is not on this storage device
				return -1;
		}
		MtpObjectHandle parent = node->getMtpParentId();
		Tree* tree = mtpmap[parent];
		if (!tree) {
				MTPE("parent tree for handle %u not found\n", parent);
				return -1;
		}
		if (node->isDir()) {
				MTPD("deleting tree from mtpmap: %u\n", handle);
				mtpmap.erase(handle);
		}

		MTPD("deleting handle: %u\n", handle);
		tree->deleteNode(handle);
		MTPD("deleted\n");
		return 0;
}

void MtpStorage::queryNodeProperties(std::vector<MtpStorage::PropEntry>& results, Node* node, uint32_t property, __attribute__((unused)) int groupCode, MtpStorageID storageID)
{
		MTPD("queryNodeProperties handle %u, path: %s\n", node->Mtpid(), getNodePath(node).c_str());
		PropEntry pe;
		pe.handle = node->Mtpid();
		pe.property = property;

		if (property == 0xffffffff)
		{
				// add all properties
				MTPD("MtpStorage::queryNodeProperties for all properties\n");
				std::vector<Node::mtpProperty> mtpprop = node->getMtpProps();
				for (size_t i = 0; i < mtpprop.size(); ++i) {
						pe.property = mtpprop[i].property;
						pe.datatype = mtpprop[i].dataType;
						pe.intvalue = mtpprop[i].valueInt;
						pe.strvalue = mtpprop[i].valueStr;
						results.push_back(pe);
				}
				return;
		}
		else if (property == 0)
		{
				// TODO: use groupCode
		}

		// single property
		// TODO: this should probably be moved to the Node class and/or merged with getObjectPropertyValue
		switch (property) {
//				case MTP_PROPERTY_OBJECT_FORMAT:
//						pe.datatype = MTP_TYPE_UINT16;
//						pe.intvalue = node->getIntProperty(MTP_PROPERTY_OBJECT_FORMAT);
//						break;

				case MTP_PROPERTY_STORAGE_ID:
						pe.datatype = MTP_TYPE_UINT32;
						pe.intvalue = storageID;
						break;

				case MTP_PROPERTY_PROTECTION_STATUS:
						pe.datatype = MTP_TYPE_UINT16;
						pe.intvalue = 0;
						break;

				case MTP_PROPERTY_OBJECT_SIZE:
				{
						pe.datatype = MTP_TYPE_UINT64;
						struct stat st;
						pe.intvalue = 0;
						if (lstat(getNodePath(node).c_str(), &st) == 0)
								pe.intvalue = st.st_size;
						break;
				}

				default:
				{
						const Node::mtpProperty& prop = node->getProperty(property);
						if (prop.property != property)
						{
								MTPD("queryNodeProperties: unknown property %x\n", property);
								return;
						}
						pe.datatype = prop.dataType;
						pe.intvalue = prop.valueInt;
						pe.strvalue = prop.valueStr;
						// TODO: all the special case stuff in MyMtpDatabase::getObjectPropertyValue is missing here
				}

		}
		results.push_back(pe);
}


