from collections import namedtuple


class Factory:
    """
    Factory module

    Methods :

        add   : add task or module
        addMany : add many task 
        get    : to get one task 
        deleteOne  :  delete one task
        deleteMany  : delete many task
        rename : rename one task 


    Example :

    >>> tasks = []
    >>> print(tasks)
        []
    >>> addTask = lambda task : tasks.append(name)
    >>> deleteTask = lambda : tasks.pop()
    >>> taskFact = Factory()
    >>> taskFact.add("taskAdd",addTask)
    >>> taskFact.add("taskDel",deleteTask)
    >>> taskFact.get.taskAdd("Take a dinner")
    >>> taskFact.get.taskAdd("Go to job")
    >>> print(tasks)
        ["Take a dinner","Go to job"]
    >>> taskFact.get.taskDel()
        "Go to job"
    >>> 
    """
    def __init__(self):
        self.module = {} # contains differents tasks or module 

    @property
    def get(self): # return namedtuple of module for use it 
        """
        to get one task /module 
        Example :

        >>> taskFact = Factory()
        >>> taskFact.add("taskAdd",addTask)
        >>> taskFact.add("taskDel",delTask)
        >>> task.Fact.get.tasAdd("New task")
        >>> task.Fact.get.tasAdd("last task")
        >>> task.Fact.get.taskDel()
        """

        if len(self.module) > 0:
            args = list(self.module.keys())
            add = namedtuple("Fact",args)
            _module = add(**self.module)
            return _module
        return "Not Data added"

    def add(self,key,value): # add task or module 
        """
        ARGS : 
            key:str     name for your task/module
            value:str   your task/module

        Example :

        >>> taskFact = Factory()
        >>> taskFact.add("taskAdd",addTask)
        """
        self.module[key] = value

    def addMany(self,list_data): # add one or many task 
        """
        ARGS    :
            list_data:list      contains list of tuple/list (key,value)

        Example :

        >>> tasks_for_add = [("taskAdd",addTask),("taskDel",delTask)]
        >>> taskFact = Factory()
        >>> taskFact.addMany(tasks_for_add)
        """
        for data in list_data:
            self.module[data[0]] =data[1]

    def deleteOne(self,key): # delete one task
        """
        ARGS    :
            key:str     key for the task/module

        Example :

        >>> taskFact = Factory()
        >>> taskFact.deleteOne("taskAdd")
        """
        del self.module[key]

    def deleteMany(self,tasks:list): # delete many task
        """
        ARGS    :
            tasks:list      contains list of keys
        
        Example :

        >>> tasks_for_delete = ["taskAdd","taskDel]
        >>> taskFact = Factory()
        >>> taskFact.deleteMany(tasks_for_delete)
        """
        for task in  task:
            self.deleteOne(task)

    def rename(self,old_name,new_name): # rename one task ( just key not value)
        """
        ARGS    :
            old_name:str    oldname of the key
            new_name:str    new name for task    
        
        Example :
        
        >>> taskFact =Factory()
        >>> taskFact.rename("taskAdd","newTask")
        """
        
        value = self.module[old_name]

        self.module[new_name] = value