#!/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 = \
"""
"""

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='/opt/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()
