'''
Created on Oct 11, 2012

An interior node in the directory tree

@author: carr
'''
from DirTreeNode import DirTreeNode
from DirTreeLeafNode import DirTreeLeafNode
import dtel.AssignOption

class DirTreeInteriorNode(DirTreeNode):


    def __init__(self,name) :
        '''
        
        :param name: the directory/file name assoicated with this node
        '''
        self.name = name
        self.typeId = -1    # unique type identifier associated with this tree node
        self.levelId = -1  # unique clearance,category securlity level id for this node
        self.flags = 0 # recursive or static assignment
        self.children = [] # the children of this node in the tree
 
    
    def addChild(self, name) :
        '''
        Add an interior node as a child of an interior node
        :param name: the directory/file name associated with the child
        '''
        child = DirTreeInteriorNode(name)
        self.children.append(child)
        
        return child
    
    def addLeaf(self, name) :
        '''
        Add a child that is a leaf node
        :param name: the directory/file name associated with the child
        '''
        child = DirTreeLeafNode(name)
        self.children.append(child)
    
    def getLeaf(self) :
        '''
        Get the first child of this node that is a leaf node
        '''
        for child in self.children :
            if isinstance(child,DirTreeLeafNode) :
                return child
        return None

    def getPrefix(self, path) :
        '''
        Return the prefix (before the first '/') for a path
        :param path: a file system path
        '''
        slashIndex = path.find('/')

        if slashIndex == -1 :
            name = path
        else :
            name = path[0:slashIndex]
        
        return name

    def getSuffix(self, path) :
        '''
        Return the suffix (after the first '/') for a path
        :param path: a file system path
        '''
        slashIndex = path.find('/')

        if slashIndex == -1 :
            return ""
        else :
            return path[slashIndex+1:len(path)]
        
    def findChild(self, name) :
        '''
        Find the child of a node with a particular name, return -1 if not found
        :param name: a text string associated iwth a file or diretory
        '''
        
        for child in self.children :
            if name == child.getName() :
                return child
        
        return -1
    
    def findSubTree(self, path) :
        '''
        Find a subtree associated with a path, return -1 if not found
        :param path: a file system path
        '''
        name = self.getPrefix(path)

        subTree = self.findChild(name)

        if subTree == -1 :
            return -1
        else :
            path = self.getSuffix(path)
            if len(path) == 0 :
                return subTree.findSubTree(path)
            else :
                return subTree
    
    def assignType(self, typeId,  flags) :
        '''
        Assign a type to a subtree (potentially recursive)
        :param typeId: a unique type identifier
        :param flags: is the assignment static or recursive
        '''
        self.typeId = typeId
        self.flags = flags
        
        if (flags & dtel.AssignOption.RECURSIVE != 0) :
            for child in self.children : 
                child.assignType(typeId, flags);
        else :
            leaf = self.getLeaf()
            if leaf != None :
                leaf.assignType(typeId, flags);
 
    def assignSecurityLevel(self, levelId,  flags) :
        '''
        Assign a security level to a subtree (potentially recursive)
        :param typeId: a unique type identifier
        :param flags: is the assignment recursive
        '''
        self.levelId = levelId
        self.flags = flags
        
        if (flags & dtel.AssignOption.RECURSIVE != 0) :
            for child in self.children : 
                child.assignSecurityLevel(levelId, flags);
        else :
            leaf = self.getLeaf()
            if leaf != None :
                leaf.assignSecurityLevel(levelId, flags);
    

    def addToTree(self, path) :
        '''
        Add a subtree ot the directory tree associated with a particular path
        :param path: a file system path
        '''
        if len(path) == 0 :
            self.addLeaf(self.getName())
        else :
            name = self.getPrefix(path)
            
            child = self.findChild(name);
            
            if child == -1 :
                child = self.addChild(name);
           
            path = self.getSuffix(path);
            child.addToTree(path);
