def __verify_circular_dependency_in_list(task_id, dependency_id, chat_id):
    """
    return True means that are circular dependency
    return False means that aren't circular dependency
    """

    dependency = db.search_Task(dependency_id, chat_id)

    if dependency.dependencies == '':
        return False
    else:
        total_result = False
        list_of_dependencies = dependency.dependencies.split(',')

        for i in list_of_dependencies:
            if i == '':
                continue
            task = db.search_Task(i, chat_id)
            another_dependency = dependency.dependencies.split(',')
            if task_id in another_dependency:
                return True
            else:
                parcial_result = __verify_circular_dependency_in_list(task_id, task.id, chat_id)
                total_result = total_result | parcial_result

        return total_result
def rename_task(chat_id, msg):
    """
    This method will rename a specific task.
    :param chat_id: specify the current chat.
    :param msg: get the params passed after /rename.
    """
    # This variable will contain the new name of the task.
    text = ''
    if msg != '':
        if len(msg.split(' ', 1)) > 1:
            text = msg.split(' ', 1)[1]
        # Getting the id.
        msg = msg.split(' ', 1)[0]

    if not msg.isdigit():
        send_message("You must inform the task id", chat_id)
    else:
        task_id = int(msg)
        task = db.search_Task(task_id, chat_id)
        # If message doesn't have a new name.
        if text == '':
            send_message("You want to modify task {}, but you didn't provide any new text".format(task_id), chat_id)
            return

        old_text = task.name
        task.name = text
        db.session.commit()
        send_message("Task {} redefined from {} to {}".format(task_id, old_text, text), chat_id)
def priority_task(chat_id, msg):
    """
    This method will set the task priority.
    :param chat_id: Specify the current chat.
    :param msg: Contains a task id and their priority.
    """
    text = ''
    if msg != '':
        if len(msg.split(' ', 1)) > 1:
            text = msg.split(' ', 1)[1]
        msg = msg.split(' ', 1)[0]

    if not msg.isdigit():
        send_message("You must inform the task id", chat_id)
    else:
        task_id = int(msg)
        task = db.search_Task(task_id, chat_id)

        if text == '':
            task.priority = ''
            send_message("_Cleared_ all priorities from task {}".format(task_id), chat_id)
        else:
            if text.lower() not in ['high', 'medium', 'low']:
                send_message("The priority *must be* one of the following: high, medium, low", chat_id)
            else:
                task.priority = text.lower()
                send_message("*Task {}* priority has priority *{}*".format(task_id, text.lower()), chat_id)
        db.session.commit()
def create_issue(chat_id, msg):
    task_id = int(msg)
    task = db.search_Task(task_id, chat_id)
    #body = "Duedate: "+task.duedate
    if make_github_issue(task.name, [task.status, 'create_by_bot']):
        send_message("Issue created.", chat_id)
    else:
        send_message("Bad attempt.", chat_id)
def delete_task(chat_id, msg):
    """
    This method will delete a specific task.
    :param chat_id: specify the current chat.
    :param msg: Contains an id that specify a specific task.
    """
    if not msg.isdigit():
        send_message("You must inform the task id", chat_id)
    else:
        task_id = int(msg)
        task = db.search_Task(task_id, chat_id)
        for t in task.dependencies.split(',')[:-1]:
            t = db.search_Task(int(t), chat_id)
            t.parents = t.parents.replace('{},'.format(task.id), '')
        db.session.delete(task)
        db.session.commit()
        send_message("Task [[{}]] deleted".format(task_id), chat_id)
def duplicate_task(chat_id, msg):
    """
    This method will duplicate a specific task.
    :param chat_id: specify the current chat.
    :param msg: contains an id that specifies a specific task.
    """
    if not msg.isdigit():
        send_message("You must inform the task id", chat_id)
    else:
        task_id = int(msg)
        task = db.search_Task(task_id, chat_id)

        dtask = Task(chat=task.chat, name=task.name, status=task.status, dependencies=task.dependencies,
                     parents=task.parents, priority=task.priority, duedate=task.duedate)
        db.session.add(dtask)

        for t in task.dependencies.split(',')[:-1]:
            t = db.search_Task(int(t), chat_id)
            t.parents += '{},'.format(dtask.id)

        db.session.commit()
        send_message("New task *TODO* [[{}]] {} with duedate [[{}]]".format(dtask.id, dtask.name), chat_id, task.duedate)
def dependson_task(chat_id, msg):
    text = ''
    if msg != '':
        if len(msg.split(' ', 1)) > 1:
            text = msg.split(' ', 1)[1]
        msg = msg.split(' ', 1)[0]

    if not msg.isdigit():
        send_message("You must inform the task id", chat_id)
    else:
        task_id = int(msg)
        task = db.search_Task(task_id, chat_id)

        if text == '':
            for i in task.dependencies.split(',')[:-1]:
                i = int(i)
                t = db.search_Task(i, chat_id)
                t.parents = t.parents.replace('{},'.format(task.id), '')

            task.dependencies = ''
            send_message("Dependencies removed from task {}".format(task_id), chat_id)
        else:
            for depid in text.split(' '):
                if not depid.isdigit():
                    send_message("All dependencies ids must be numeric, and not {}".format(depid), chat_id)
                else:
                    if __verify_circular_dependency_in_list(msg, text, chat_id):
                        send_message('Can not has circular dependency', chat_id)
                    else:
                        depid = int(depid)
                        taskdep = db.search_Task(task_id, chat_id)
                        taskdep.parents += str(task.id) + ','

                        deplist = task.dependencies.split(',')
                        if str(depid) not in deplist:
                            task.dependencies += str(depid) + ','

        db.session.commit()
        send_message("Task {} dependencies up to date".format(task_id), chat_id)
def done_task(chat_id, msg):
    """
    This method will show the done task.
    :param chat_id: Specify the current chat.
    :param msg: Contains a task id.
    """
    if not msg.isdigit():
        send_message("You must inform the task id", chat_id)
    else:
        task_id = int(msg)
        task = db.search_Task(task_id, chat_id)
        task.status = 'DONE'
        db.session.commit()
        send_message("*DONE* task [[{}]] {}".format(task.id, task.name), chat_id)
def todo_task(chat_id, msg):
    """
    This method will show the todo list.
    :param chat_id: Specify the current chat.
    :param msg: Contains a task id.
    """
    if not msg.isdigit():
        send_message("You must inform the task id", chat_id)
    else:
        task_id = int(msg)
        task = db.search_Task(task_id, chat_id)
        task.status = 'TODO'
        db.session.commit()
        send_message("*TODO* task [[{}]] {} with duedate [[{}]]".format(task.id, task.name), chat_id, task.duedate)
def __deps_text(task, chat_id, preceed=''):
    text = ''

    for i in range(len(task.dependencies.split(',')[:-1])):
        line = preceed
        task = db.search_Task(int(task.dependencies.split(',')[:-1][i]), chat_id)
        dep = query.one()

        icon = '\U0001F195'
        if dep.status == 'DOING':
            icon = '\U000023FA'
        elif dep.status == 'DONE':
            icon = '\U00002611'

        if i + 1 == len(task.dependencies.split(',')[:-1]):
            line += '└── [[{}]] {} {}\n'.format(dep.id, icon, dep.name)
            line += __deps_text(dep, chat_id, preceed + '    ')
        else:
            line += '├── [[{}]] {} {}\n'.format(dep.id, icon, dep.name)
            line += __deps_text(dep, chat_id, preceed + '│   ')

        text += line

    return text