<commit_before>package seedu.jimi.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import javafx.collections.ObservableList;
import seedu.jimi.model.event.Event;
import seedu.jimi.model.tag.Tag;
import seedu.jimi.model.tag.UniqueTagList;
import seedu.jimi.model.task.DeadlineTask;
import seedu.jimi.model.task.FloatingTask;
import seedu.jimi.model.task.ReadOnlyTask;
import seedu.jimi.model.task.UniqueTaskList;

/**
 * Wraps all data at the address-book level
 * Duplicates are not allowed (by .equals comparison)
 */
public class TaskBook implements ReadOnlyTaskBook {

    private final UniqueTaskList<ReadOnlyTask> tasks;
    private final UniqueTaskList<ReadOnlyTask> deadlineTasks;
    private final UniqueTaskList<ReadOnlyTask> events;
    private final UniqueTagList tags;

    {
        tasks = new UniqueTaskList();
        deadlineTasks = new UniqueTaskList();
        events = new UniqueTaskList();
        tags = new UniqueTagList();
    }

    public TaskBook() {}

    /**
     * Tasks and Tags are copied into this addressbook
     */
    public TaskBook(ReadOnlyTaskBook toBeCopied) {
        this(toBeCopied.getUniqueTaskList(), toBeCopied.getUniqueDeadlineTaskList(), toBeCopied.getUniqueEventList(),
                toBeCopied.getUniqueTagList());
    }

    /**
     * Tasks and Tags are copied into this addressbook
     */
    public TaskBook(UniqueTaskList tasks, UniqueTaskList deadlineTasks, UniqueTaskList events, UniqueTagList tags) {
        resetData(tasks.getInternalList(), deadlineTasks.getInternalList(), events.getInternalList(),
                tags.getInternalList());
    }

    public static ReadOnlyTaskBook getEmptyTaskBook() {
        return new TaskBook();
    }

//// list overwrite operations

    public ObservableList<ReadOnlyTask> getTasks() {
        return tasks.getInternalList();
    }
    
    public ObservableList<ReadOnlyTask> getDeadlineTasks() {
        return deadlineTasks.getInternalList();
    }
    
    public ObservableList<ReadOnlyTask> getEvents() {
        return events.getInternalList();
    }

    public void setReadOnlyTasks(List<ReadOnlyTask> tasks) {
        this.tasks.getInternalList().setAll(tasks);
    }
    
    public void setDeadlineTasks(List<ReadOnlyTask> deadlineTasks) {
        this.deadlineTasks.getInternalList().setAll(deadlineTasks);
    }
    
    public void setEvents(List<ReadOnlyTask> events) {
        this.events.getInternalList().setAll(events);
    }

    public void setTags(Collection<Tag> tags) {
        this.tags.getInternalList().setAll(tags);
    }

    public void resetData(Collection<? extends ReadOnlyTask> newTasks, Collection<? extends ReadOnlyTask> newDeadlineTasks,
            Collection<? extends ReadOnlyTask> newEvents, Collection<Tag> newTags) {
        ArrayList<ReadOnlyTask> newTaskList = new ArrayList<ReadOnlyTask>();
        ArrayList<ReadOnlyTask> newDeadlineTaskList = new ArrayList<ReadOnlyTask>();
        ArrayList<ReadOnlyTask> newEventList = new ArrayList<ReadOnlyTask>();

        for (ReadOnlyTask t : newTasks) {
            if (t instanceof DeadlineTask) {
                newDeadlineTaskList.add(new DeadlineTask((DeadlineTask) t));
            } else if (t instanceof Event) {
                newEventList.add(new Event((Event) t));
            } else {
                newTaskList.add(new FloatingTask((FloatingTask) t));
            }
        }
        
        setReadOnlyTasks(newTaskList);
        setDeadlineTasks(newDeadlineTaskList);
        setEvents(newEventList);
        setTags(newTags);
    }

    public void resetData(ReadOnlyTaskBook newData) {
        resetData(newData.getTaskList(), newData.getDeadlineTaskList(), newData.getEventList(), newData.getTagList());
    }

//// task-level operations

    /**
     * Adds a task to the address book.
     * Also checks the new task's tags and updates {@link #tags} with any new tags found,
     * and updates the Tag objects in the task to point to those in {@link #tags}.
     *
     * @throws UniqueTaskList.DuplicateTaskException if an equivalent task already exists.
     */
    public void addTask(ReadOnlyTask p) throws UniqueTaskList.DuplicateTaskException {
        syncTagsWithMasterList((ReadOnlyTask) p);
        tasks.add(p);
    }

    /**
     * Ensures that every tag in this task:
     *  - exists in the master list {@link #tags}
     *  - points to a Tag object in the master list
     */
    private void syncTagsWithMasterList(ReadOnlyTask task) {
        final UniqueTagList taskTags = task.getTags();
        tags.mergeFrom(taskTags);

        // Create map with values = tag object references in the master list
        final Map<Tag, Tag> masterTagObjects = new HashMap<>();
        for (Tag tag : tags) {<commit_msg>TaskBook: implement methods to add to seperate lists<commit_after>package seedu.jimi.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import javafx.collections.ObservableList;
import seedu.jimi.model.event.Event;
import seedu.jimi.model.tag.Tag;
import seedu.jimi.model.tag.UniqueTagList;
import seedu.jimi.model.task.DeadlineTask;
import seedu.jimi.model.task.FloatingTask;
import seedu.jimi.model.task.ReadOnlyTask;
import seedu.jimi.model.task.UniqueTaskList;

/**
 * Wraps all data at the address-book level
 * Duplicates are not allowed (by .equals comparison)
 */
public class TaskBook implements ReadOnlyTaskBook {

    private final UniqueTaskList<ReadOnlyTask> tasks;
    private final UniqueTaskList<ReadOnlyTask> deadlineTasks;
    private final UniqueTaskList<ReadOnlyTask> events;
    private final UniqueTagList tags;

    {
        tasks = new UniqueTaskList();
        deadlineTasks = new UniqueTaskList();
        events = new UniqueTaskList();
        tags = new UniqueTagList();
    }

    public TaskBook() {}

    /**
     * Tasks and Tags are copied into this addressbook
     */
    public TaskBook(ReadOnlyTaskBook toBeCopied) {
        this(toBeCopied.getUniqueTaskList(), toBeCopied.getUniqueDeadlineTaskList(), toBeCopied.getUniqueEventList(),
                toBeCopied.getUniqueTagList());
    }

    /**
     * Tasks and Tags are copied into this addressbook
     */
    public TaskBook(UniqueTaskList tasks, UniqueTaskList deadlineTasks, UniqueTaskList events, UniqueTagList tags) {
        resetData(tasks.getInternalList(), deadlineTasks.getInternalList(), events.getInternalList(),
                tags.getInternalList());
    }

    public static ReadOnlyTaskBook getEmptyTaskBook() {
        return new TaskBook();
    }

//// list overwrite operations

    public ObservableList<ReadOnlyTask> getTasks() {
        return tasks.getInternalList();
    }
    
    public ObservableList<ReadOnlyTask> getDeadlineTasks() {
        return deadlineTasks.getInternalList();
    }
    
    public ObservableList<ReadOnlyTask> getEvents() {
        return events.getInternalList();
    }

    public void setReadOnlyTasks(List<ReadOnlyTask> tasks) {
        this.tasks.getInternalList().setAll(tasks);
    }
    
    public void setDeadlineTasks(List<ReadOnlyTask> deadlineTasks) {
        this.deadlineTasks.getInternalList().setAll(deadlineTasks);
    }
    
    public void setEvents(List<ReadOnlyTask> events) {
        this.events.getInternalList().setAll(events);
    }

    public void setTags(Collection<Tag> tags) {
        this.tags.getInternalList().setAll(tags);
    }

    public void resetData(Collection<? extends ReadOnlyTask> newTasks, Collection<? extends ReadOnlyTask> newDeadlineTasks,
            Collection<? extends ReadOnlyTask> newEvents, Collection<Tag> newTags) {
        ArrayList<ReadOnlyTask> newTaskList = new ArrayList<ReadOnlyTask>();
        ArrayList<ReadOnlyTask> newDeadlineTaskList = new ArrayList<ReadOnlyTask>();
        ArrayList<ReadOnlyTask> newEventList = new ArrayList<ReadOnlyTask>();

        for (ReadOnlyTask t : newTasks) {
            if (t instanceof DeadlineTask) {
                newDeadlineTaskList.add(new DeadlineTask((DeadlineTask) t));
            } else if (t instanceof Event) {
                newEventList.add(new Event((Event) t));
            } else {
                newTaskList.add(new FloatingTask((FloatingTask) t));
            }
        }
        
        setReadOnlyTasks(newTaskList);
        setDeadlineTasks(newDeadlineTaskList);
        setEvents(newEventList);
        setTags(newTags);
    }

    public void resetData(ReadOnlyTaskBook newData) {
        resetData(newData.getTaskList(), newData.getDeadlineTaskList(), newData.getEventList(), newData.getTagList());
    }

//// task-level operations

    /**
     * Adds a task to the address book.
     * Also checks the new task's tags and updates {@link #tags} with any new tags found,
     * and updates the Tag objects in the task to point to those in {@link #tags}.
     *
     * @throws UniqueTaskList.DuplicateTaskException if an equivalent task already exists.
     */
    public void addTask(ReadOnlyTask p) throws UniqueTaskList.DuplicateTaskException {
        syncTagsWithMasterList((ReadOnlyTask) p);
        tasks.add(p);
    }
    
    /**
     * Adds a deadlineTask to the address book.
     * Also checks the new task's tags and updates {@link #tags} with any new tags found,
     * and updates the Tag objects in the task to point to those in {@link #tags}.
     *
     * @throws UniqueTaskList.DuplicateTaskException if an equivalent task already exists.
     */
    public void addDeadlineTask(ReadOnlyTask p) throws UniqueTaskList.DuplicateTaskException {
        syncTagsWithMasterList((ReadOnlyTask) p);
        deadlineTasks.add(p);
    }
    
    /**
     * Adds an event to the address book.
     * Also checks the new task's tags and updates {@link #tags} with any new tags found,
     * and updates the Tag objects in the task to point to those in {@link #tags}.
     *
     * @throws UniqueTaskList.DuplicateTaskException if an equivalent task already exists.
     */
    public void addEvent(ReadOnlyTask p) throws UniqueTaskList.DuplicateTaskException {
        syncTagsWithMasterList((ReadOnlyTask) p);
        events.add(p);
    }

    /**
     * Ensures that every tag in this task:
     *  - exists in the master list {@link #tags}
     *  - points to a Tag object in the master list
     */
    private void syncTagsWithMasterList(ReadOnlyTask task) {
        final UniqueTagList taskTags = task.getTags();
        tags.mergeFrom(taskTags);

        // Create map with values = tag object references in the master list
        final Map<Tag, Tag> masterTagObjects = new HashMap<>();
        for (Tag tag : tags) {
{'fraction_non_alphanumeric': 0.0938493685836286, 'fraction_numerical': 0.0, 'mean_word_length': 3.1197604790419162, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3097231', 'n_tokens_mistral': 3064, 'n_tokens_neox': 3037, 'n_words': 795}