// @@author A0130195M

package jfdi.logic.commands;

import jfdi.logic.events.SearchDoneEvent;
import jfdi.logic.interfaces.Command;
import jfdi.storage.apis.TaskAttributes;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.stream.Collectors;

/**
 * @author Liu Xinan
 */
public class SearchCommand extends Command {

    private HashSet<String> keywords;

    private SearchCommand(Builder builder) {
        this.keywords = builder.keywords;
    }

    public HashSet<String> getKeywords() {
        return keywords;
    }

    public static class Builder {

        HashSet<String> keywords = new HashSet<>();

        public Builder addKeyword(String keyword) {
            this.keywords.add(keyword);
            return this;
        }

        public Builder addKeywords(Collection<String> keywords) {
            this.keywords.addAll(keywords);
            return this;
        }

        public SearchCommand build() {
            return new SearchCommand(this);
        }

    }

    @Override
    public void execute() {
        ArrayList<TaskAttributes> results = new ArrayList<>();
        results.addAll(getFullMatches());
        results.addAll(getPartialMatches());

        eventBus.post(new SearchDoneEvent(results, keywords));
        System.out.println(results);
    }

    private ArrayList<TaskAttributes> getFullMatches() {
        return taskDb.getAll().stream().filter(task -> {
            for (String keyword : keywords) {
                if (!task.getDescription().matches(String.format("(?i:.*\\b%s\\b.*)", keyword))) {
                    return false;
                }
            }
            return true;
        }).collect(Collectors.toCollection(ArrayList::new));
    }

    private ArrayList<TaskAttributes> getPartialMatches() {
        return taskDb.getAll().stream().filter(task -> {
            int matches = 0;
            for (String keyword : keywords) {
                if (task.getDescription().matches(String.format("(?i:.*\\b%s\\b.*)", keyword))) {
                    matches++;
                }
            }
            return matches != 0 && matches != keywords.size();
        }).collect(Collectors.toCollection(ArrayList::new));
    }

    @Override
    public void undo() {
        assert false;
    }

}

@@ -402,16 +402,64 @@
 words;%0A%0A
+    private ArrayList%3CTaskAttributes%3E results;%0A%0A
     priv
@@ -611,32 +611,115 @@
 eywords;%0A    %7D%0A%0A
+    public ArrayList%3CTaskAttributes%3E getResults() %7B%0A        return results;%0A    %7D%0A%0A
     public stati
@@ -1218,34 +1218,8 @@
     
- ArrayList%3CTaskAttributes%3E
  res
@@ -1399,45 +1399,8 @@
 ));%0A
-        System.out.println(results);%0A
     

Allow to get results from `SearchCommand`