package de.renew.lola2.analysis;

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

/**
 * DirectLolaResult is a concrete implementation of the LolaResult interface.
 * It encapsulates the result of a LoLA analysis, including the output, error,
 * and status of the analysis.
 */
public class DirectLolaResult implements LolaResult {
    private static org.apache.log4j.Logger _logger =
        org.apache.log4j.Logger.getLogger(DirectLolaResult.class);

    // Pattern constants for better performance
    private static final String ANALYSIS_RESULT_PATTERN_STRING =
        ".*\"analysis\".*\"result\":\\s*(true|false)";
    private static final Pattern ANALYSIS_RESULT_PATTERN =
        Pattern.compile(ANALYSIS_RESULT_PATTERN_STRING);

    private String _output;
    private String _error;
    private LolaResultStatus _status;

    /**
     * Constructs a DirectLolaResult with the given return value, output, and error.
     *
     * @param returnValue The return value from the LoLA command execution.
     * @param output The standard output from the LoLA command.
     * @param error The standard error output from the LoLA command.
     */
    public DirectLolaResult(int returnValue, String output, String error) {
        this._output = output;
        this._error = error;
        this._status = checkResultStatus(returnValue, output);
    }

    private LolaResultStatus checkResultStatus(int returnValue, String output) {
        LolaResultStatus status;

        if (returnValue == 0) {
            // the LoLA JSON result should be in format:
            // {
            //     "analysis": {
            //         "result": true/false,
            //         ...
            //     },
            //     ...
            // }
            Matcher matcher = ANALYSIS_RESULT_PATTERN.matcher(output);

            if (matcher.find()) {
                boolean result = Boolean.parseBoolean(matcher.group(1));
                status = result ? LolaResultStatus.YES : LolaResultStatus.NO;
            } else {
                status = LolaResultStatus.ERROR;
                _logger.error("LoLA call returned an error.");
            }
        } else {
            status = LolaResultStatus.ERROR;
            _logger.error("LoLA call returned an error.");
        }
        return status;
    }

    /**
     * Returns the output of the LoLA command execution.
     *
     * @return The standard output from the LoLA command.
     */
    public String getOutput() {
        return this._output;
    }

    /**
     * Returns the error output of the LoLA command execution.
     *
     * @return The standard error output from the LoLA command.
     */
    public String getError() {
        return this._error;
    }

    /**
     * Returns the status of the LoLA analysis.
     *
     * @return The status of the analysis as a LolaResultStatus.
     */
    @Override
    public LolaResultStatus getStatus() {
        return this._status;
    }
}