<commit_before>package edu.dynamic.dynamiz.storage;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.TreeMap;

import edu.dynamic.dynamiz.logic.FileHandler;
import edu.dynamic.dynamiz.structure.EventItem;
import edu.dynamic.dynamiz.structure.TaskItem;
import edu.dynamic.dynamiz.structure.ToDoItem;

/**
 * Defines the storage class holding the list of tasks and events.
 * @author zixian
 * ToDo: Confirm the return type of parser and pass complexity of creating/updating items
 * 	to this class instead of Controller.
 */
public class Storage {
    //Main data members
    private ArrayList<ToDoItem> mainList;	//The main list
    private ArrayList<ToDoItem> toDoItemList;	//Holds items without any dates
    private ArrayList<EventItem> eventList;	//Holds events
    private ArrayList<TaskItem> taskList;	//Holds deadline tasks
    private TreeMap<String, ToDoItem> searchTree;	//Maps each item to its ID for faster search by ID
    
    //Constructor
    public Storage(){
	mainList = FileHandler.getListFromFile();
	searchTree = new TreeMap<String, ToDoItem>();
	toDoItemList = new ArrayList<ToDoItem>();
	eventList = new ArrayList<EventItem>();
	taskList = new ArrayList<TaskItem>();
	Iterator<ToDoItem> itr = mainList.iterator();
	ToDoItem temp;
	while(itr.hasNext()){
	    temp = itr.next();
	    searchTree.put(temp.getId(), temp);
	    if(temp instanceof TaskItem){
		taskList.add((TaskItem)temp);
	    } else if(temp instanceof EventItem){
		eventList.add((EventItem)temp);
	    } else{
		toDoItemList.add(temp);
	    }
	}
    }
    
    /**
     * Adds the given item to the list. For use by CommandDelete's undo method.
     * @return The TodoItem that is added to the list.
     */
    public ToDoItem addItem(ToDoItem item){
	mainList.add(item);
	searchTree.put(item.getId(), item);
	if(item instanceof TaskItem){
	    taskList.add((TaskItem)item);
	} else if(item instanceof EventItem){
	    eventList.add((EventItem)item);
	} else{
	    toDoItemList.add(item);
	}
	try {
	    FileHandler.writeListToFile(mainList, "output.txt");
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
	return item;	
    }
    
    /**
     * Updates the item with the given id with the specified changes.
     * @return The updated ToDoItem.
     * Signature and implementation to be edited after confirming parameters returned by parser.
     * Exceptions to be thrown on fail cases.
     */
    public ToDoItem[] updateItem(String id){
	ToDoItem[] list = new ToDoItem[2];
	ToDoItem target = searchTree.get(id);
	
	//Makes a copy of the current version of the object
	if(target instanceof TaskItem){
	    list[0] = new TaskItem((TaskItem)target);
	} else if(target instanceof EventItem){
	    list[0] = new EventItem((EventItem)target);
	} else{
	    list[0] = new ToDoItem(target);
	}
	//Use mutator methods to update the target object.
	list[1] = target;
	
	try {
	    FileHandler.writeListToFile(mainList, "output.txt");
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
	return list;	
    }
    
    /**
     * Undoes the update done by the Command object executing the update method.
     * item must be such that its ID matches an existing item in the storage.
     * For use by CommandUpdate's undo method.
     */
    public void undoUpdate(ToDoItem item){
	removeItem(item.getId());
	addItem(item);
    }
    
    /**
     * Returns the list of tasks and events in an array sorted in lexicographical order of their ID.
     * @return An array of ToDoItem objects sorted in lexicographical order of their ID
     * 		or null if the list is empty.
     */
    public ToDoItem[] getList(){
	if(mainList.isEmpty()){
	    return null;
	}
	return mainList.toArray(new ToDoItem[mainList.size()]);
    }
    
    /**
     * Returns a list of events sorted in lexicographical order of their ID.
     * @return An array of EventItem objects sorted in lexicographical order of their ID
     * 		or null if the list is empty.
     */
    public EventItem[] getEvents(){
	if(eventList.isEmpty()){
	    return null;
	}
	Collections.sort(eventList);
	return eventList.toArray(new EventItem[eventList.size()]);
    }
    
    /**
     * Returns a list of deadline tasks in lexicographical order or their ID.
     * @return An array of TaskItem objects sorted in lexicographical order of their ID
     * 		or null if the list is empty.
     */
    public TaskItem[] getTasks(){
	if(taskList.isEmpty()){
	    return null;
	}
	Collections.sort(taskList);
	return taskList.toArray(new TaskItem[taskList.size()]);
    }
    
    /**
     * Gets the list of events sorted in ascending order of start date.
     * @return An array of EventItem sorted in ascending order by start date
     * 		or null if the list is empty.
     * Implementation is currently only a stub, to be properly implemented when use case requirements
     * are confirmed.
     */
    public EventItem[] getListSortedByStartDate(){
	if(eventList.isEmpty()){
	    return null;
	}
	Collections.sort(eventList);
	return eventList.toArray(new EventItem[eventList.size()]);
    }
    
    /**
     * Gets the list of events sorted in ascending order of end date.
     * @return An array of EventItem sorted in ascending order by start date
     * 		or null if the list is empty.
     * Implementation is currently only a stub, to be properly implemented when use case requirements
     * are confirmed.
     */
    public EventItem[] getListSortedByEndDate(){
	if(eventList.isEmpty()){
	    return null;
	}
	Collections.sort(eventList);
	return eventList.toArray(new EventItem[eventList.size()]);
    }
    
    /**
     * Gets the list of deadline tasks sorted in ascending order of their deadlines.
     * @return An array of TaskItem objects sorted in ascending order of their deadlines.
     * Implementation is currently only a stub, to be properly implemented when use case requirements
     * are confirmed.
     */
    public TaskItem[] getListSortedByDeadline(){
	if(taskList.isEmpty()){<commit_msg>Changes some method signatures in Storage class<commit_after>package edu.dynamic.dynamiz.storage;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.TreeMap;

import edu.dynamic.dynamiz.logic.FileHandler;
import edu.dynamic.dynamiz.structure.EventItem;
import edu.dynamic.dynamiz.structure.TaskItem;
import edu.dynamic.dynamiz.structure.ToDoItem;

/**
 * Defines the storage class holding the list of tasks and events.
 * @author zixian
 * ToDo: Confirm the return type of parser and pass complexity of creating/updating items
 * 	to this class instead of Controller.
 */
public class Storage {
    //Main data members
    private ArrayList<ToDoItem> mainList;	//The main list
    private ArrayList<ToDoItem> toDoItemList;	//Holds items without any dates
    private ArrayList<EventItem> eventList;	//Holds events
    private ArrayList<TaskItem> taskList;	//Holds deadline tasks
    private TreeMap<String, ToDoItem> searchTree;	//Maps each item to its ID for faster search by ID
    
    //Constructor
    public Storage(){
	mainList = FileHandler.getListFromFile();
	searchTree = new TreeMap<String, ToDoItem>();
	toDoItemList = new ArrayList<ToDoItem>();
	eventList = new ArrayList<EventItem>();
	taskList = new ArrayList<TaskItem>();
	Iterator<ToDoItem> itr = mainList.iterator();
	ToDoItem temp;
	while(itr.hasNext()){
	    temp = itr.next();
	    searchTree.put(temp.getId(), temp);
	    if(temp instanceof TaskItem){
		taskList.add((TaskItem)temp);
	    } else if(temp instanceof EventItem){
		eventList.add((EventItem)temp);
	    } else{
		toDoItemList.add(temp);
	    }
	}
    }
    
    /**
     * Adds a new item with the specified information into the storage.
     * @return The ToDoItem that is added to the storage by this operation.
     * Signature and implementation to be updated.
     */
    public ToDoItem addItem(){
	return null;
    }
    
    /**
     * Adds the given item to the list. For use by CommandDelete's undo method.
     * @return The TodoItem that is added to the list.
     */
    public ToDoItem addItem(ToDoItem item){
	mainList.add(item);
	searchTree.put(item.getId(), item);
	if(item instanceof TaskItem){
	    taskList.add((TaskItem)item);
	} else if(item instanceof EventItem){
	    eventList.add((EventItem)item);
	} else{
	    toDoItemList.add(item);
	}
	try {
	    FileHandler.writeListToFile(mainList, "output.txt");
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
	return item;	
    }
    
    /**
     * Updates the item with the given id with the specified changes.
     * @return The updated ToDoItem.
     * Signature and implementation to be edited after confirming parameters returned by parser.
     */
    public ToDoItem[] updateItem(String id){
	ToDoItem[] list = new ToDoItem[2];
	ToDoItem target = searchTree.get(id);
	
	//Makes a copy of the current version of the object
	if(target instanceof TaskItem){
	    list[0] = new TaskItem((TaskItem)target);
	} else if(target instanceof EventItem){
	    list[0] = new EventItem((EventItem)target);
	} else{
	    list[0] = new ToDoItem(target);
	}
	//Use mutator methods to update the target object.
	list[1] = target;
	
	try {
	    FileHandler.writeListToFile(mainList, "output.txt");
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
	return list;	
    }
    
    /**
     * Undoes the update done by the Command object executing the update method.
     * item must be such that its ID matches an existing item in the storage.
     * For use by CommandUpdate's undo method.
     */
    public void undoUpdate(ToDoItem item){
	removeItem(item.getId());
	addItem(item);
    }
    
    /**
     * Returns the list of tasks and events in an array sorted in lexicographical order of their ID.
     * @return An array of ToDoItem objects sorted in lexicographical order of their ID
     * 		or null if the list is empty.
     */
    public ToDoItem[] getList(){
	if(mainList.isEmpty()){
	    return null;
	}
	return mainList.toArray(new ToDoItem[mainList.size()]);
    }
    
    /**
     * Returns a list of events sorted in lexicographical order of their ID.
     * @return An array of EventItem objects sorted in lexicographical order of their ID
     * 		or null if the list is empty.
     */
    public EventItem[] getEvents(){
	if(eventList.isEmpty()){
	    return null;
	}
	return eventList.toArray(new EventItem[eventList.size()]);
    }
    
    /**
     * Returns a list of deadline tasks in lexicographical order or their ID.
     * @return An array of TaskItem objects sorted in lexicographical order of their ID
     * 		or null if the list is empty.
     */
    public TaskItem[] getTasks(){
	if(taskList.isEmpty()){
	    return null;
	}
	return taskList.toArray(new TaskItem[taskList.size()]);
    }
    
    /**
     * Gets the list of events sorted in ascending order of start date.
     * @return An array of EventItem sorted in ascending order by start date
     * 		or null if the list is empty.
     * Implementation is currently only a stub, to be properly implemented when use case requirements
     * are confirmed.
     */
    public EventItem[] getEventsSortedByStartDate(){
	if(eventList.isEmpty()){
	    return null;
	}
	Collections.sort(eventList);
	return eventList.toArray(new EventItem[eventList.size()]);
    }
    
    /**
     * Gets the list of events sorted in ascending order of end date.
     * @return An array of EventItem sorted in ascending order by start date
     * 		or null if the list is empty.
     * Implementation is currently only a stub, to be properly implemented when use case requirements
     * are confirmed.
     */
    public EventItem[] getEventsSortedByEndDate(){
	if(eventList.isEmpty()){
	    return null;
	}
	Collections.sort(eventList);
	return eventList.toArray(new EventItem[eventList.size()]);
    }
    
    /**
     * Gets the list of deadline tasks sorted in ascending order of their deadlines.
     * @return An array of TaskItem objects sorted in ascending order of their deadlines.
     * Implementation is currently only a stub, to be properly implemented when use case requirements
     * are confirmed.
     */
    public TaskItem[] getTasksSortedByDeadline(){
	if(taskList.isEmpty()){
{'fraction_non_alphanumeric': 0.0950204474380563, 'fraction_numerical': 0.0008018603159329645, 'mean_word_length': 3.18242790073776, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, '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': '2357649', 'n_tokens_mistral': 3725, 'n_tokens_neox': 3618, 'n_words': 1256}