<commit_before>package linenux.command.parser;

import java.time.LocalDateTime;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import linenux.command.result.CommandResult;
import linenux.control.TimeParserManager;
import linenux.model.Task;
import linenux.util.Either;

/**
 * Parses new details of task to be edited.
 */
public class EditTaskArgumentParser {
	public static final String ARGUMENT_FORMAT = "TASK_NAME [n/NEW_TASK_NAME] [st/START_TIME] [et/END_TIME] [#/CATEGORY]...";

	private TimeParserManager timeParserManager;

	public EditTaskArgumentParser(TimeParserManager timeParserManager) {
		this.timeParserManager = timeParserManager;
	}

	public Either<Task, CommandResult> parse(Task original, String argument) {
		Either<String, CommandResult> newTaskName = extractNewTaskName(argument);
		if (newTaskName.isRight()) {
			return Either.right(newTaskName.getRight());
		}

		Either<LocalDateTime, CommandResult> startTime = extractStartTime(argument);
		if (startTime.isRight()) {
			return Either.right(startTime.getRight());
		}

		Either<LocalDateTime, CommandResult> endTime = extractEndTime(argument);
		if (endTime.isRight()) {
			return Either.right(endTime.getRight());
		}

		String actualTaskName = newTaskName.getLeft();
		LocalDateTime actualStartTime = startTime.getLeft();
		LocalDateTime actualEndTime = endTime.getLeft();

		if (actualTaskName == null) {
			actualTaskName = original.getTaskName();
		}
		if (actualStartTime == null) {
			actualStartTime = original.getStartTime();
		}
		if (actualEndTime == null) {
			actualEndTime = original.getEndTime();
		}

		if (actualStartTime != null && actualEndTime == null) {
			return Either.right(makeStartTimeWithoutEndTimeResult());
		}
		if (actualStartTime != null && actualEndTime != null && actualEndTime.compareTo(actualStartTime) < 0) {
			return Either.right(makeEndTimeBeforeStartTimeResult());
		}

		Task task = new Task(actualTaskName, actualStartTime, actualEndTime);

		return Either.left(task);
	}

	private Either<String, CommandResult> extractNewTaskName(String argument) {
		Matcher matcher = Pattern.compile("(^|.*?)n/(?<name>.*?)((n|st|et)/.*)?$").matcher(argument);

		if (matcher.matches() && matcher.group("name") != null) {
			return Either.left(matcher.group("name").trim());
		} else {
			return Either.left(null);
		}
	}

	private Either<LocalDateTime, CommandResult> extractStartTime(String argument) {
		Matcher matcher = Pattern.compile("(^|.*? )st/(?<startTime>.*?)(\\s+et/.*)?").matcher(argument);

		if (matcher.matches() && matcher.group("startTime") != null) {
			return parseDateTime(matcher.group("startTime").trim());
		} else {
			return Either.left(null);
		}
	}

	private Either<LocalDateTime, CommandResult> extractEndTime(String argument) {
		Matcher matcher = Pattern.compile("(^|.*? )et/(?<endTime>.*?)(\\s+st/.*)?$").matcher(argument);
<commit_msg>EditCommand no longer accepts empty task names<commit_after>package linenux.command.parser;

import java.time.LocalDateTime;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import linenux.command.result.CommandResult;
import linenux.control.TimeParserManager;
import linenux.model.Task;
import linenux.util.Either;

/**
 * Parses new details of task to be edited.
 */
public class EditTaskArgumentParser {
	public static final String ARGUMENT_FORMAT = "TASK_NAME [n/NEW_TASK_NAME] [st/START_TIME] [et/END_TIME] [#/CATEGORY]...";

	private TimeParserManager timeParserManager;

	public EditTaskArgumentParser(TimeParserManager timeParserManager) {
		this.timeParserManager = timeParserManager;
	}

	public Either<Task, CommandResult> parse(Task original, String argument) {
		Either<String, CommandResult> newTaskName = extractNewTaskName(argument);
		if (newTaskName.isRight()) {
			return Either.right(newTaskName.getRight());
		}

		Either<LocalDateTime, CommandResult> startTime = extractStartTime(argument);
		if (startTime.isRight()) {
			return Either.right(startTime.getRight());
		}

		Either<LocalDateTime, CommandResult> endTime = extractEndTime(argument);
		if (endTime.isRight()) {
			return Either.right(endTime.getRight());
		}

		String actualTaskName = newTaskName.getLeft();
		LocalDateTime actualStartTime = startTime.getLeft();
		LocalDateTime actualEndTime = endTime.getLeft();

		if (actualTaskName == null) {
			actualTaskName = original.getTaskName();
		}
		if (actualStartTime == null) {
			actualStartTime = original.getStartTime();
		}
		if (actualEndTime == null) {
			actualEndTime = original.getEndTime();
		}

		if (actualStartTime != null && actualEndTime == null) {
			return Either.right(makeStartTimeWithoutEndTimeResult());
		}
		if (actualStartTime != null && actualEndTime != null && actualEndTime.compareTo(actualStartTime) < 0) {
			return Either.right(makeEndTimeBeforeStartTimeResult());
		}

		Task task = new Task(actualTaskName, actualStartTime, actualEndTime);

		return Either.left(task);
	}

	private Either<String, CommandResult> extractNewTaskName(String argument) {
		Matcher matcher = Pattern.compile("(^|.*?)n/(?<name>.*?)((n|st|et)/.*)?$").matcher(argument);

		if (matcher.matches() && matcher.group("name") != null) {
			if (matcher.group("name").trim().length() > 0) {
				return Either.left(matcher.group("name").trim());
			} else {
				return Either.right(makeInvalidArgumentResult());
			}
		} else {
			return Either.left(null);
		}
	}

	private Either<LocalDateTime, CommandResult> extractStartTime(String argument) {
		Matcher matcher = Pattern.compile("(^|.*? )st/(?<startTime>.*?)(\\s+et/.*)?").matcher(argument);

		if (matcher.matches() && matcher.group("startTime") != null) {
			return parseDateTime(matcher.group("startTime").trim());
		} else {
			return Either.left(null);
		}
	}

	private Either<LocalDateTime, CommandResult> extractEndTime(String argument) {
		Matcher matcher = Pattern.compile("(^|.*? )et/(?<endTime>.*?)(\\s+st/.*)?$").matcher(argument);

{'fraction_non_alphanumeric': 0.14817309311331875, 'fraction_numerical': 0.0005051355447044957, 'mean_word_length': 5.27906976744186, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 24, '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': '7659783', 'n_tokens_mistral': 2010, 'n_tokens_neox': 1832, 'n_words': 348}