package edu.hm.hafner.analysis.parser;

import java.util.Optional;
import java.util.regex.Matcher;

import org.apache.commons.lang3.StringUtils;

import edu.hm.hafner.analysis.Issue;
import edu.hm.hafner.analysis.IssueBuilder;
import edu.hm.hafner.analysis.LookaheadParser;
import edu.hm.hafner.analysis.Severity;
import edu.hm.hafner.util.LookaheadStream;

/**
 * A parser for the GHS Multi compiler warnings.
 *
 * @author Joseph Boulos
 */
public class GhsMultiParser extends LookaheadParser {
    private static final long serialVersionUID = 8149238560432255036L;

    /**
     * Regex Pattern to match start of Warning / Error. Groups are used to identify FileName, StartLine, Type, Category,
     * Start of message.
     */
    private static final String GHS_MULTI_WARNING_PATTERN =
            "\"(.*)\"\\,\\s*line\\s*(\\d+)(?:\\s+\\(col\\.\\s*(\\d+)\\))?:\\s*(warning|error)\\s*([^:]+):\\s*(?m)([^\\^]*)";

    /** Regex Pattern to match the ending of the Warning / Error Message. */
    private static final String MESSAGE_END_REGEX = "\\s*\\^";

    /**
     * Creates a new instance of {@link GhsMultiParser}.
     */
    public GhsMultiParser() {
        super(GHS_MULTI_WARNING_PATTERN);
    }

    @Override
    protected Optional<Issue> createIssue(final Matcher matcher, final LookaheadStream lookahead,
            final IssueBuilder builder) {
        String type = StringUtils.capitalize(matcher.group(4));
        String messageStart = matcher.group(6);

        String message = extractMessage(messageStart, lookahead);

        if (StringUtils.isNotBlank(matcher.group(3))) {
            return builder.setFileName(matcher.group(1))
                    .setLineStart(matcher.group(2))
                    .setColumnStart(matcher.group(3))
                    .setCategory(matcher.group(5))
                    .setMessage(message)
                    .setSeverity(Severity.guessFromString(type))
                    .buildOptional();
        }

        return builder.setFileName(matcher.group(1))
                .setLineStart(matcher.group(2))
                .setCategory(matcher.group(5))
                .setMessage(message)
                .setSeverity(Severity.guessFromString(type))
                .buildOptional();
    }

    /**
     * Go through all following lines appending the message until a line with only the ^ Symbol is found.
     *
     * @param messageStart
     *         start of the message
     * @param lookahead
     *         lines used for message creation
     *
     * @return concatenated message string
     */
    private String extractMessage(final String messageStart, final LookaheadStream lookahead) {
        StringBuilder messageBuilder = new StringBuilder(messageStart).append("\n");

        while (!lookahead.hasNext(MESSAGE_END_REGEX) && lookahead.hasNext()) {
            messageBuilder.append(lookahead.next()).append("\n");
        }

        return messageBuilder.toString();
    }

    @Override
    protected boolean isLineInteresting(final String line) {
        return line.contains("warning") || line.contains("error");
    }
}


@@ -787,25 +787,20 @@
 RN =
-%0A            %22%5C%22(
+ %22%5C%22(?%3Cfile%3E
 .*)%5C
@@ -811,25 +811,49 @@
 %5C%5Cs*line%5C%5Cs*
-(
+%22%0A            + %22(?%3Cline%3E
 %5C%5Cd+)(?:%5C%5Cs+
@@ -866,16 +866,25 @@
 %5C%5C.%5C%5Cs*(
+?%3Ccolumn%3E
 %5C%5Cd+)%5C%5C)
@@ -890,17 +890,45 @@
 ))?:%5C%5Cs*
-(
+%22%0A            + %22(?%3Cseverity%3E
 warning%7C
@@ -938,16 +938,27 @@
 or)%5C%5Cs*(
+?%3Ccategory%3E
 %5B%5E:%5D+):%5C
@@ -965,16 +965,26 @@
 %5Cs*(?m)(
+?%3Cmessage%3E
 %5B%5E%5C%5C%5E%5D*)
@@ -1493,17 +1493,26 @@
 r.group(
-4
+%22severity%22
 ));%0A    
@@ -1551,17 +1551,25 @@
 r.group(
-6
+%22message%22
 );%0A%0A    
@@ -1643,75 +1643,8 @@
     
-if (StringUtils.isNotBlank(matcher.group(3))) %7B%0A            return 
 buil
@@ -1665,33 +1665,38 @@
 e(matcher.group(
-1
+%22file%22
 ))%0A             
@@ -1690,36 +1690,32 @@
                 
-  
-  
 .setLineStart(ma
@@ -1730,70 +1730,17 @@
 oup(
-2))%0A                    .setColumnStart(matcher.group(3))%0A    
+%22line%22))%0A
     
@@ -1774,32 +1774,37 @@
 tcher.group(
-5))%0A    
+%22category%22))%0A
             
@@ -1820,36 +1820,32 @@
 essage(message)%0A
-    
                 
@@ -1880,32 +1880,34 @@
 romString(type))
+;%0A
 %0A               
@@ -1903,311 +1903,157 @@
     
-            .buildOptional();%0A        %7D%0A%0A        return builder.setFileName(matcher.group(1))%0A                .setLineStart(matcher.group(2))%0A                .setCategory(matcher.group(5))%0A                .setMessage(message)%0A                .setSeverity(Severity.guessFromString(type))%0A                
+if (StringUtils.isNotBlank(matcher.group(%22column%22))) %7B%0A            builder.setColumnStart(matcher.group(%22column%22));%0A        %7D%0A%0A        return builder
 .bui

Fix review findings