# Bryan Schumaker (5 / 20 / 2011)

import threading
from libsaria import storage
from libsaria.sources import attrs

library_lock   = threading.Lock()
lock_library   = library_lock.acquire
unlock_library = library_lock.release
get_dattr      = attrs.get_dattr
get_count      = attrs.get_count

# Map directory -> dict()
lib_dict = None
LIB_FILE = "library"

def load():
	global lib_dict
	saved_lib = storage.load_obj(LIB_FILE, dict)
	if saved_lib.__class__ != dict:
		saved_lib = dict()
	lock_library()
	lib_dict = saved_lib
	unlock_library()

# NOTE: You should already be holding the lock when you call this
def save():
	storage.save_obj(LIB_FILE, lib_dict)

def reset():
	global lib_dict
	lock_library()
	lib_dict = {}
	save()
	unlock_library()

def add_path(path):
	lock_library()
	lib_dict.setdefault(path, dict())
	unlock_library()

def rm_path(path):
	lock_library()
	del lib_dict[path]
	save()
	unlock_library()

def list_paths():
	res = []
	lock_library()
	for path, lib in lib_dict.iteritems():
		res.append((path, lib))
	unlock_library()
	return res

def find_id(id):
	for src, tracks in lib_dict.iteritems():
		track = tracks.get(id, None)
		if track != None:
			return track

def size():
	res = 0
	lock_library()
	for src, tracks in lib_dict.iteritems():
		res += len(tracks)
	unlock_library()
	return res

def get_attrs(id, *attrs):
	lock_library()
	track = find_id(id)
	if track == None:
		unlock_library()
		return None

	get = track.__dict__.get
	res = []
	for attr in attrs:
		if attr == "id":
			res.append(id)
		elif attr == "like":
			res.append(get_dattr(id, attr))
		elif attr == "count":
			res.append(get_count(id))
		else:
			res.append(get(attr))
	unlock_library()
	return res

def all_attrs(id, attrs):
	lock_library()
	found = False
	track = find_id(id)
	if track != None:
		attrs.update(track.__dict__)
		attrs["id"] = id
		found = True
	unlock_library()
	return found
