package gov.hhs.onc.dcdt.mail.smtp.command.impl;

import gov.hhs.onc.dcdt.dns.utils.ToolDnsNameUtils;
import gov.hhs.onc.dcdt.mail.MailAddress;
import gov.hhs.onc.dcdt.mail.impl.MailAddressImpl;
import gov.hhs.onc.dcdt.mail.smtp.SmtpCommandException;
import gov.hhs.onc.dcdt.mail.smtp.SmtpReplyCode;
import gov.hhs.onc.dcdt.mail.smtp.command.SmtpCommand;
import gov.hhs.onc.dcdt.mail.smtp.command.SmtpCommandType;
import gov.hhs.onc.dcdt.mail.smtp.impl.AbstractSmtpMessage;
import gov.hhs.onc.dcdt.mail.smtp.impl.SmtpReplyImpl;
import gov.hhs.onc.dcdt.mail.utils.ToolMailAddressUtils;
import gov.hhs.onc.dcdt.utils.ToolStringUtils;
import gov.hhs.onc.dcdt.utils.ToolStringUtils.ToolStrBuilder;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;

public abstract class AbstractSmtpCommand extends AbstractSmtpMessage<SmtpCommandType> implements SmtpCommand {
    public final static int MAX_PATH_LEN = 256;

    public final static String PATH_DELIM = ":";
    public final static String PATH_ROUTE_DELIM = ",";

    public final static String PATTERN_STR_PATH_ROUTE = "(?:" + ToolMailAddressUtils.MAIL_ADDR_PART_DELIM + ToolDnsNameUtils.PATTERN_STR_DNS_NAME_REL_BASE
        + PATH_ROUTE_DELIM + "?)(?<=[" + PATH_ROUTE_DELIM + ToolMailAddressUtils.MAIL_ADDR_PART_DELIM + ToolDnsNameUtils.PATTERN_STR_DNS_NAME_LBL_CHAR_ANY
        + "]{1,253})(?<!" + PATH_ROUTE_DELIM + ")";

    public final static String PATTERN_STR_PATH = "^(?:" + "(?:" + PATTERN_STR_PATH_ROUTE + ")+" + PATH_DELIM + ")?("
        + ToolMailAddressUtils.PATTERN_STR_MAIL_ADDR_BASE + ")(?<=[" + PATH_DELIM + PATH_ROUTE_DELIM + ToolMailAddressUtils.MAIL_ADDR_PART_DELIM
        + ToolDnsNameUtils.PATTERN_STR_DNS_NAME_LBL_CHAR_ANY + "]{1," + MAX_PATH_LEN + "})$";

    public final static Pattern PATTERN_PATH = Pattern.compile(PATTERN_STR_PATH);

    protected AbstractSmtpCommand(SmtpCommandType type) {
        super(type);
    }

    @Override
    public String toString() {
        ToolStrBuilder builder = this.parametersToString(new ToolStrBuilder());

        if (!builder.isEmpty()) {
            builder.insert(0, StringUtils.SPACE);
        }

        builder.insert(0, this.type.getId());
        builder.append(ToolStringUtils.CRLF);

        return builder.build();
    }

    protected static MailAddress parsePath(int maxNumParams, String prefix, String str) throws SmtpCommandException {
        String[] params = parseParameters(1, maxNumParams, str);

        if (!StringUtils.startsWith(params[0], prefix) || !StringUtils.endsWith(params[0], ToolMailAddressUtils.MAIL_ADDR_PART_PERSONAL_ADDR_SUFFIX)) {
            throw new SmtpCommandException(new SmtpReplyImpl(SmtpReplyCode.SYNTAX_ERROR_ARGUMENTS, String.format("Required syntax: '%slocal@domain%s'", prefix,
                ToolMailAddressUtils.MAIL_ADDR_PART_PERSONAL_ADDR_SUFFIX)));
        }

        int pathLen =
            (params[0] = StringUtils.removeEnd(StringUtils.removeStart(params[0], prefix), ToolMailAddressUtils.MAIL_ADDR_PART_PERSONAL_ADDR_SUFFIX)).length();

        if (pathLen > MAX_PATH_LEN) {
            throw new SmtpCommandException(new SmtpReplyImpl(SmtpReplyCode.SYNTAX_ERROR_ARGUMENTS, String.format("Path too long: %d > %d", pathLen,
                MAX_PATH_LEN)));
        }

        Matcher pathMatcher = PATTERN_PATH.matcher(params[0]);

        if (!pathMatcher.matches()) {
            throw new SmtpCommandException(new SmtpReplyImpl(SmtpReplyCode.SYNTAX_ERROR_ARGUMENTS, String.format("Malformed email address: %s", params[0])));
        }

        return new MailAddressImpl(pathMatcher.group(1));
    }

    protected static String[] parseParameters(int numParams, String str) throws SmtpCommandException {
        return parseParameters(numParams, numParams, str);
    }

    protected static String[] parseParameters(int minNumParams, int maxNumParams, String str) throws SmtpCommandException {
        return parseParameters((strSplit) -> StringUtils.split(strSplit, StringUtils.SPACE), minNumParams, maxNumParams, str);
    }

    protected static String[] parseParameters(Function<String, String[]> splitter, int numParams, String str) throws SmtpCommandException {
        return parseParameters(splitter, numParams, numParams, str);
    }

    protected static String[] parseParameters(Function<String, String[]> splitter, int minNumParams, int maxNumParams, String str) throws SmtpCommandException {
        String[] params = splitter.apply(str);

        if ((minNumParams >= 0) && (params.length < minNumParams)) {
            throw new SmtpCommandException(new SmtpReplyImpl(SmtpReplyCode.SYNTAX_ERROR_ARGUMENTS, String.format("Too few parameters: %d < %d", params.length,
                minNumParams)));
        }

        if ((maxNumParams >= 0) && (params.length > maxNumParams)) {
            throw new SmtpCommandException(new SmtpReplyImpl(SmtpReplyCode.SYNTAX_ERROR_ARGUMENTS, String.format("Too many parameters: %d > %d", params.length,
                maxNumParams)));
        }

        return params;
    }

    protected ToolStrBuilder parametersToString(ToolStrBuilder builder) {
        return builder;
    }
}

@@ -2452,32 +2452,71 @@
 mandException %7B%0A
+    %09%0A        str = str.toUpperCase();%0A
         String%5B%5D
@@ -2560,24 +2560,33 @@
 rams, str);%0A
+         
 %0A        if 
@@ -2587,16 +2587,17 @@
    if (!
+(
 StringUt
@@ -2724,16 +2724,17 @@
 SUFFIX))
+)
  %7B%0A     
@@ -3380,33 +3380,32 @@
 N)));%0A        %7D%0A
-%0A
         Matcher 
@@ -3451,17 +3451,16 @@
 ms%5B0%5D);%0A
-%0A
         
@@ -3649,33 +3649,32 @@
 %5D)));%0A        %7D%0A
-%0A
         return n
@@ -3712,16 +3712,30 @@
 group(1)
+.toLowerCase()
 );%0A    %7D
@@ -5268,9 +5268,8 @@
 %0A    %7D%0A%7D
-%0A

fix smtp mail sensitivity