#!/usr/bin/env python

import os
import json

class ConfigurationException(Exception):
	pass

class StorageConfiguration(dict):
	MANDATORY_KEYS = [
						"WORKDIR",
						"BLACKLIST",
						"TAGFILE",
						"PATHFILE",
					]

	def __init__(self, filename = None, override = None):
		dict.__init__(self)

		if filename is not None:
			self._loadFrom(filename)

		if override is not None:
			self._fromHash(override)
		self._check()

	def _loadFrom(self, filename):
		f = open(filename, "r")
		h = json.load(f)
		self._fromHash(h)
		f.close()
	
	def _fromHash(self, override):
		for key,value in override.items():
			self[key] = value

	def _check(self):
		for key in self.MANDATORY_KEYS:
			if not self.has_key(key):
				raise ConfigurationException("Missing key: %s"%key)

class StorageDriver:
	def __init__(self, directory, blacklist):
		self.dir = os.path.abspath(directory)
		self.blacklist = blacklist
		self.fileIndex = {}
		self.buildIndex(self.dir, "")
		self.buildBlacklist("%s/%s"%(directory,"BLACKLIST"))
		self.tagFile = open("%s/%s"%(directory,"TAGFILE"), "a")

	def buildBlacklist(self, filename):
		try:
			f = open(filename, "r")
			for line in f:
				self.blacklist.add(line.strip())
			f.close()
		except IOError:
			pass
		self.blacklistFile = filename

	def buildIndex(self, directory, root):
		directory = os.path.realpath(directory)
		try:
			os.makedirs(directory)
		except:
			pass

		listing = os.listdir(directory)

		for item in listing:
			if os.path.isdir("%s/%s"%(directory,item)):
				self.buildIndex("%s/%s"%(directory,item),"%s/%s"%(root,item))
			else:
				self.fileIndex["%s/%s"%(root,item)] = "%s/%s"%(directory,item)
				self.blacklist.add("%s/%s"%(root,item))

	def __str__(self):
		s = ""
		for key,value in self.fileIndex.items():
			s+="%s:%s\n"%(key,value)
		return s

	def getRealPath(self, path):
		return "%s/%s"%(self.dir, path)

	def hasFile(self, path):
		if self.fileIndex.has_key(path):
			self.blacklist.add(path)
			return True
		return False

	def getFile(self, path):
		return open(self.fileIndex[path],"r").read()

	def putFile(self, path, data):
		realpath = self.getRealPath(path)
		try:
			os.makedirs(os.path.split(realpath)[0])
		except:
			pass
		self.fileIndex[path] = realpath

		f = open(realpath, "w")
		f.write(data)
		f.close()
		self.blacklist.add(path, noregex=True)

	def putTag(self, path, tag):
		self.tagFile.writelines("%s,%s\n"%(path,tag))

	def sync(self):
		self.tagFile.close()
		f = open(self.blacklistFile,"a")
		for path in self.blacklist:
			f.writelines("%s\n"%path.rawpattern)
		f.close()

