from ciscoconfparse import CiscoConfParse
import hashlib
import difflib

class audit:
    
    def configuration_must_have(self,input_parent,input_config,show_command_output,show_command):
        audit = False
        actual_child_config = "No Configuration Found: {}".format(input_config)
        parent_config = ""
        actual_parent_config = ""
        self.parse = CiscoConfParse(show_command_output.splitlines())
        parent_obj = self.parse.find_objects(r"{}".format(input_parent))
        for obj in parent_obj:
            
            audit = obj.has_child_with(r"{}".format(input_config))
            if audit == True:
                actual_parent_config = obj.text
                actual_child_config = " ".join([ x.text.strip() for x in obj.re_search_children(r"{}".format(input_config))])
                break


        expect_configuration = "{}\n{}".format(input_parent,input_config)
        actual_configuration = "{}\n{}".format(actual_parent_config,actual_child_config)
        if audit != True:
            raise AssertionError("\n\nExpected Output: \n\n{}\n\nActual Output: \n\n{}\n\n".format(expect_configuration,actual_configuration))
            
        else:
            print("\n\nExpected Output: \n\n{}\n\nActual Output: \n\n{}\n\n".format(expect_configuration,actual_configuration))

    def sanitize(inputstring):
        output = ""
        for x in inputstring.split("\n"):
            output = output + x.strip() + "\n"
        return output
        
    def hash_diff(self,expected_configuration,actual_configuration):
        actual_configuration = "\n".join(actual_configuration.split("\n")[2:-2]).strip()
        actual_configuration = audit.sanitize(actual_configuration)
        expected_configuration = audit.sanitize(expected_configuration)
        expected_hash = hashlib.sha224(expected_configuration.encode()).hexdigest()
        actual_hash = hashlib.sha224(actual_configuration.encode()).hexdigest()

        d = difflib.Differ()
        diff = d.compare(actual_configuration.split("\n"), expected_configuration.split("\n"))
        diff_output = '\n'.join(diff)

        if expected_hash == actual_hash:
            print("\n\nExpected Output: \n\n{}\n\nActual Output: \n\n{}\n\n".format(expected_configuration,actual_configuration))
        else:
            raise AssertionError("\n\nExpected Output: \n\n{}\n\nActual Output: \n\n{}\n\nDifference: \n\n{}\n\n".format(expected_configuration,actual_configuration,diff_output))

