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

default_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='/etc/planetstack/plstackapi_config'):
        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 _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()
