#!/usr/bin/python
import sys
import os
import time
import ConfigParser
import tempfile
import codecs
from StringIO import StringIO
from util.xml import Xml

default_config = \
"""
"""

XOS_ROOT = "/opt/planetstack"
DEFAULT_CONFIG_FN = os.path.join(XOS_ROOT, "xos_config")

# warning for now, remove once we're sure everyone has made the change
if (os.path.exists("/opt/planetstack/plstackapi_config") and (not os.path.exists(DEFAULT_CONFIG_FN))):
    print >> sys.stderr, "WARNING: did you forget to rename plstackapi_config to xos_config ??"

def isbool(v):
	return v.lower() in ("true", "false")

def str2bool(v):
	return v.lower() in ("true", "1")

class Config:

	def __init__(self, config_file=None):
                if (config_file==None):
                    config_file = self.get_config_fn()

		self._files = []
		self.config_path = os.path.dirname(config_file)
		self.config = ConfigParser.ConfigParser()
		self.filename = config_file
		if not os.path.isfile(self.filename):
			self.create(self.filename)
		self.load(self.filename)

        def get_config_fn(self):
             # Look for "-C <something>" to get the
             # name of the config file. Using a real OptionParser here is
             # problematic as it will throw 'no such option' errors for options
             # that it does not understand.

             last = None
             for arg in sys.argv:
                 if (last=="-C"):
                     return arg
                 last = arg

             return DEFAULT_CONFIG_FN

	def _header(self):
		header = """
DO NOT EDIT. This file was automatically generated at
%s from:

%s
""" % (time.asctime(), os.linesep.join(self._files))

		# Get rid of the surrounding newlines
		return header.strip().split(os.linesep)

	def create(self, filename):
		if not os.path.exists(os.path.dirname(filename)):
			os.makedirs(os.path.dirname(filename))
		configfile = open(filename, 'w')
		configfile.write(default_config)
		configfile.close()


	def load(self, filename):
		if filename:
			try:
				self.config.read(filename)
			except ConfigParser.MissingSectionHeaderError:
				if filename.endswith('.xml'):
					self.load_xml(filename)
				else:
					self.load_shell(filename)
			self._files.append(filename)
			self.set_attributes()

	def load_xml(self, filename):
		xml = XML(filename)
		categories = xml.xpath('//configuration/variables/category')
		for category in categories:
			section_name = category.get('id')
			if not self.config.has_section(section_name):
				self.config.add_section(section_name)
			options = category.xpath('./variablelist/variable')
			for option in options:
				option_name = option.get('id')
				value = option.xpath('./value')[0].text
				if not value:
					value = ""
				self.config.set(section_name, option_name, value)

	def load_shell(self, filename):
		f = open(filename, 'r')
		for line in f:
			try:
				if line.startswith('#'):
					continue
				parts = line.strip().split("=")
				if len(parts) < 2:
					continue
				option = parts[0]
				value = parts[1].replace('"', '').replace("'","")
				section, var = self.locate_varname(option, strict=False)
				if section and var:
					self.set(section, var, value)
			except:
				pass
		f.close()

	def locate_varname(self, varname, strict=True):
		varname = varname.lower()
		sections = self.config.sections()
		section_name = ""
		var_name = ""
		for section in sections:
			if varname.startswith(section.lower()) and len(section) > len(section_name):
				section_name = section.lower()
				var_name = varname.replace(section_name, "")[1:]
		if strict and not self.config.has_option(section_name, var_name):
			raise ConfigParser.NoOptionError(var_name, section_name)
		return (section_name, var_name)

	def set_attributes(self):
		sections = self.config.sections()
		for section in sections:
			for item in self.config.items(section):
				name = "%s_%s" % (section, item[0])
				value = item[1]
				if isbool(value):
					value = str2bool(value)
				elif value.isdigit():
					value = int(value)
				setattr(self, name, value)
				setattr(self, name.upper(), value)


	def verify(self, config1, config2, validate_method):
		return True

	def validate_type(self, var_type, value):
		return True

	@staticmethod
	def is_xml(config_file):
		try:
			x = Xml(config_file)
			return True
		except:
			return False

	@staticmethod
	def is_ini(config_file):
		try:
			c = ConfigParser.ConfigParser()
			c.read(config_file)
			return True
		except ConfigParser.MissingSectionHeaderError:
			return False


	def dump(self, sections = []):
		sys.stdout.write(output_python())

	def output_python(self, encoding = "utf-8"):
		buf = codecs.lookup(encoding)[3](StringIO())
		buf.writelines(["# " + line + os.linesep for line in self._header()])

		for section in self.sections():
			buf.write("[%s]%s" % (section, os.linesep))
			for (name,value) in self.items(section):
				buf.write("%s=%s%s" % (name,value,os.linesep))
			buf.write(os.linesep)
		return buf.getvalue()

	def output_shell(self, show_comments = True, encoding = "utf-8"):
		"""
		Return variables as a shell script.
		"""

		buf = codecs.lookup(encoding)[3](StringIO())
		buf.writelines(["# " + line + os.linesep for line in self._header()])

		for section in self.sections():
			for (name,value) in self.items(section):
				# bash does not have the concept of NULL
				if value:
					option = "%s_%s" % (section.upper(), name.upper())
					if isbool(value):
						value = str(str2bool(value))
					elif not value.isdigit():
						value = '"%s"' % value
					buf.write(option + "=" + value + os.linesep)
		return buf.getvalue()

	def output_php(self, encoding = "utf-8"):
		"""
		Return variables as a PHP script.
		"""

		buf = codecs.lookup(encoding)[3](StringIO())
		buf.write("<?php" + os.linesep)
		buf.writelines(["// " + line + os.linesep for line in self._header()])

		for section in self.sections():
			for (name,value) in self.items(section):
				option = "%s_%s" % (section, name)
				buf.write(os.linesep)
				buf.write("// " + option + os.linesep)
				if value is None:
					value = 'NULL'
				buf.write("define('%s', %s);" % (option, value) + os.linesep)

		buf.write("?>" + os.linesep)

		return buf.getvalue()

	def output_xml(self, encoding = "utf-8"):
		pass

	def output_variables(self, encoding="utf-8"):
		"""
		Return list of all variable names.
		"""

		buf = codecs.lookup(encoding)[3](StringIO())
		for section in self.sections():
			for (name,value) in self.items(section):
				option = "%s_%s" % (section,name)
				buf.write(option + os.linesep)

		return buf.getvalue()
		pass

	def write(self, filename=None):
		if not filename:
			filename = self.filename
		configfile = open(filename, 'w')
		self.config.write(configfile)

	def save(self, filename=None):
		self.write(filename)

	def __getattr__(self, attr):
		return getattr(self.config, attr)

if __name__ == '__main__':
	filename = None
	if len(sys.argv) > 1:
		filename = sys.argv[1]
		config = Config(filename)
	else:
		config = Config()
	config.dump()
