# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
import re
import os
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 = open(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):
        newLines = []
        if os.path.exists(self.fileName) and os.path.isfile(self.fileName):
            fp = open(self.fileName, "r")
            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)

            fp.close()

        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")

        open(self.fileName, "w").writelines(newLines)

    def replace_line(self, startswith,stanza,always_add=False):
        lines = [ s.strip() for s in open(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 ]
        open(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 = open(self.fileName).read(-1)
        sh = re.escape(lines)
        match = re.search(sh, fp, re.MULTILINE)
        if match is not None:
            return

        fp += lines
        open(self.fileName, "w").write(fp)
        self.backups.append([None, lines])

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

    def append_lines(self, match_lines, append_lines):
        fp = open(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 open(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)

        open(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)
