import re
import tempfile
import shutil
from utilities import bash
class configFileOps:
    class entry:
        def __init__(self, name, value, op, separator):
            self.name = name
            self.value = value
            self.state = "new"
            self.op = op
            self.separator = separator
        def setState(self, state):
            self.state = state 
        def getState(self):
            return self.state

    def __init__(self, fileName, cfg=None):
        self.fileName = fileName
        self.entries = []
        self.backups = []
        
        if cfg is not None:
            cfg.cfoHandlers.append(self)

    def addEntry(self, name, value, separator="="):
        e = self.entry(name, value, "add", separator)
        self.entries.append(e)
    
    def rmEntry(self, name, value, separator="="):
        entry = self.entry(name, value, "rm", separator)
        self.entries.append(entry)
    
    def getEntry(self, name, separator="="):
        try:
            ctx = file(self.fileName).read(-1)
            match = re.search("^" + name + ".*", ctx, re.MULTILINE)
            if match is None:
                return ""
            line = match.group(0).split(separator, 1)
            return line[1]
        except:
            return ""

    def save(self):
        fp = open(self.fileName, "r")
        newLines = []
        for line  in fp.readlines():
            matched = False
            for entry in self.entries:
                if entry.op == "add":
                    if entry.separator == "=":
                        matchString = "^\ *" + entry.name + ".*"
                    elif entry.separator == " ":
                        matchString = "^\ *" + entry.name + "\ *" + entry.value
                else:
                    if entry.separator == "=":
                        matchString = "^\ *" + entry.name + "\ *=\ *" + entry.value
                    else:
                        matchString = "^\ *" + entry.name + "\ *" + entry.value
                
                match = re.match(matchString, line)
                if match is not None:
                    if entry.op == "add" and entry.separator == "=":
                        newline = "\n" + entry.name + "=" + entry.value + "\n"
                        entry.setState("set")
                        newLines.append(newline)
                        self.backups.append([line, newline])
                        matched = True
                        break
                    elif entry.op == "rm":
                        entry.setState("set")
                        self.backups.append([line, None])
                        matched = True
                        break  
                    
            if not matched: 
                newLines.append(line)

        for entry in self.entries:
            if entry.getState() != "set":
                if entry.op == "add":
                    newline = entry.name + entry.separator + entry.value + "\n"
                    newLines.append(newline)
                    self.backups.append([None, newline])
                    entry.setState("set")

        fp.close()
        
        file(self.fileName, "w").writelines(newLines)

    def replace_line(self, startswith,stanza,always_add=False):
        lines = [ s.strip() for s in file(self.fileName).readlines() ]
        newlines = []
        replaced = False
        for line in lines:
            if re.search(startswith, line):
                if stanza is not None:
                    newlines.append(stanza)
                    self.backups.append([line, stanza])
                replaced = True
            else: newlines.append(line)
        if not replaced and always_add:
            newlines.append(stanza)
            self.backups.append([None, stanza])
        newlines = [ s + '\n' for s in newlines ]
        file(self.fileName,"w").writelines(newlines)

    def replace_or_add_line(self, startswith,stanza):
        return self.replace_line(startswith,stanza,always_add=True)

    def add_lines(self, lines, addToBackup=True):
        fp = file(self.fileName).read(-1) 
        sh = re.escape(lines)
        match = re.search(sh, fp, re.MULTILINE) 
        if match is not None:
            return
    
        fp += lines
        file(self.fileName, "w").write(fp)
        self.backups.append([None, lines])
        
    def replace_lines(self, src, dst, addToBackup=True):
        fp = file(self.fileName).read(-1) 
        sh = re.escape(src)
        if dst is None:
            dst = ""
        repl,nums = re.subn(sh, dst, fp)
        if nums <=0:
            return
        file(self.fileName, "w").write(repl)
        if addToBackup:
            self.backups.append([src, dst])

    def append_lines(self, match_lines, append_lines):
        fp = file(self.fileName).read(-1)
        sh = re.escape(match_lines)
        match = re.search(sh, fp, re.MULTILINE)
        if match is None:
            return

        sh = re.escape(append_lines)
        if re.search(sh, fp, re.MULTILINE) is not None:
            return

        newlines = []
        for line in file(self.fileName).readlines():
            if re.search(match_lines, line) is not None:
                newlines.append(line + append_lines)
                self.backups.append([line, line + append_lines])
            else:
                newlines.append(line)

        file(self.fileName, "w").writelines(newlines)
            
    def backup(self):
        for oldLine, newLine in self.backups:
            if newLine is None:
                self.add_lines(oldLine, False)
            else:
                self.replace_lines(newLine, oldLine, False)
            
if __name__ == '__main__':
    cfo = configFileOps("./sudoers")
    #cloud ALL = NOPASSWD : ALL
    cfo.addEntry("cloud ALL ", "NOPASSWD : ALL")
    cfo.rmEntry("Defaults", "requiretty", " ")
    #cfo.addEntry("zone", "test", " ")
    cfo.save()
