<commit_before>package com.onlythenaive.concept.ecmarunner.api;

import java.util.ArrayList;
import java.util.List;

import com.onlythenaive.concept.ecmarunner.convention.ImmutableByContract;
import com.onlythenaive.concept.ecmarunner.convention.PublishedApi;

/**
 * Script(s) execution result.
 *
 * Contains results of an invoice execution. Designed to be immutable.
 *
 * @see Invoice
 * @see TerminationType
 * @see ResultValueType
 *
 * @author <NAME>
 */
@PublishedApi
@ImmutableByContract
public final class Result {

    private final Invoice invoice;
    private final List<LogRecord> logRecords;
    private final TerminationType terminationType;
    private final Object value;
    private final ResultValueType valueType;

    public Result(final Invoice invoice,
                  final List<LogRecord> logRecords,
                  final TerminationType terminationType,
                  final Object value,
                  final ResultValueType valueType) {
        if (invoice == null) {
            throw new NullPointerException("Execution invoice cannot be null");
        }
        this.invoice = invoice;
        if (logRecords == null) {
            throw new NullPointerException("Execution log records cannot be null");
        }
        this.logRecords = new ArrayList<>(logRecords);
        if (terminationType == null) {
            throw new NullPointerException("Termination type cannot be null");
        }
        this.terminationType = terminationType;
        this.value = value;
        if (valueType == null) {
            throw new NullPointerException("Result value type cannot be null");
        }
        // TODO: check if value type corresponds to the value
        this.valueType = valueType;
    }

    /**
     * Related execution invoice
     *
     * @return execution invoice.
     *
     * @see Invoice
     */
    public Invoice getInvoice() {
        return this.invoice;
    }

    /**
     * Gets a list of log records which were produced during execution of the invoice.
     *
     * @return list of log records.
     *
     * @see LogRecord
     */
    public List<LogRecord> getLogRecords() {
        return new ArrayList<>(this.logRecords);
    }

    /**
     * Gets the type of execution termination.
     *
     * @return termination type.
     *
     * @see TerminationType
     */
    public TerminationType getTerminationType() {
        return this.terminationType;
    }

    /**
     * Gets a resulting value of this execution if any.
     *
     * @return execution result value or <code>null</code>.
     */
    public Object getValue() {
        // TODO: analyze value type
        return this.value;
    }

    /**
     * Gets the type of this execution result value
     *
     * @return result value type.
     *
     * @see ResultValueType
     */
    public ResultValueType getValueType() {
        return this.valueType;
    }
}<commit_msg>Result improved (type matching, converting)<commit_after>package com.onlythenaive.concept.ecmarunner.api;

import java.util.ArrayList;
import java.util.List;

import com.onlythenaive.concept.ecmarunner.convention.ImmutableByContract;
import com.onlythenaive.concept.ecmarunner.convention.PublishedApi;

/**
 * Script execution result.
 *
 * Contains results of an invoice execution. Designed to be immutable.
 *
 * @see Invoice
 * @see LogRecord
 * @see TerminationType
 * @see ResultValueType
 *
 * @author <NAME>
 */
@PublishedApi
@ImmutableByContract
public final class Result {

    private final Invoice invoice;
    private final List<LogRecord> logRecords;
    private final TerminationType terminationType;
    private final Object value;
    private final ResultValueType valueType;

    /**
     * Creates a new execution invoice result.
     *
     * @param invoice initial execution invoice.
     * @param logRecords log records produced during execution of the invoice.
     * @param terminationType execution termination type.
     * @param value execution result value object.
     * @param valueType result value type.
     *
     * @see Invoice
     * @see LogRecord
     * @see TerminationType
     * @see ResultValueType
     */
    public Result(final Invoice invoice,
                  final List<LogRecord> logRecords,
                  final TerminationType terminationType,
                  final Object value,
                  final ResultValueType valueType) {
        if (invoice == null) {
            throw new NullPointerException("Execution invoice cannot be null");
        }
        this.invoice = invoice;
        if (logRecords == null) {
            throw new NullPointerException("Execution log records cannot be null");
        }
        this.logRecords = new ArrayList<>(logRecords);
        if (terminationType == null) {
            throw new NullPointerException("Termination type cannot be null");
        }
        this.terminationType = terminationType;
        this.value = value;
        if (valueType == null) {
            throw new NullPointerException("Result value type cannot be null");
        }
        this.valueType = valueType;
        if (valueTypeMismatch()) {
            throw new IllegalArgumentException("Value type and actual result value mismatch");
        }
    }

    /**
     * Related execution invoice
     *
     * @return execution invoice.
     *
     * @see Invoice
     */
    public Invoice getInvoice() {
        return this.invoice;
    }

    /**
     * Gets a list of log records which were produced during execution of the invoice.
     *
     * @return list of log records.
     *
     * @see LogRecord
     */
    public List<LogRecord> getLogRecords() {
        return new ArrayList<>(this.logRecords);
    }

    /**
     * Gets the type of execution termination.
     *
     * @return termination type.
     *
     * @see TerminationType
     */
    public TerminationType getTerminationType() {
        return this.terminationType;
    }

    /**
     * Gets a resulting value of this execution if any.
     *
     * @return execution result value or <code>null</code>.
     */
    public Object getValue() {
        return this.value;
    }

    /**
     * Gets a resulting value of this execution if any as <code>List</code> (copied).
     *
     * @return execution result value or <code>null</code>.
     */
    public List<?> getValueAsList() {
        return new ArrayList<>((List<?>) this.value);
    }

    /**
     * Gets a resulting value of this execution if any as <code>Boolean</code>.
     *
     * @return execution result value or <code>null</code>.
     */
    public Boolean getValueAsBoolean() {
        return (Boolean) this.value;
    }

    /**
     * Gets a resulting value of this execution if any as <code>Number</code>.
     *
     * @return execution result value or <code>null</code>.
     */
    public Number getValueAsNumber() {
        return (Number) this.value;
    }

    /**
     * Gets a resulting value of this execution if any as <code>String</code>.
     *
     * @return execution result value or <code>null</code>.
     */
    public String getValueAsString() {
        return (String) this.value;
    }

    /**
     * Gets the type of this execution result value
     *
     * @return result value type.
     *
     * @see ResultValueType
     */
    public ResultValueType getValueType() {
        return this.valueType;
    }

    private boolean valueTypeMatch() {
        switch (valueType) {
            case ARRAY:
                return this.value instanceof List<?>;
            case BOOLEAN:
                return this.value instanceof Boolean;
            case FUNCTION:
            case NULL:
            case UNDEFINED:
                return this.value == null;
            case NUMBER:
                return this.value instanceof Number;
            case STRING:
                return this.value instanceof String;
            default:
                return true;
        }
    }

    private boolean valueTypeMismatch() {
        return !valueTypeMatch();
    }
}
{'fraction_non_alphanumeric': 0.08736776602364654, 'fraction_numerical': 0.0, 'mean_word_length': 2.1575638506876227, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, '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': '680744', 'n_tokens_mistral': 2152, 'n_tokens_neox': 2058, 'n_words': 665}