/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.scxml2.model;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.scxml2.Context;
import org.apache.commons.scxml2.Evaluator;
import org.apache.commons.scxml2.EventBuilder;
import org.apache.commons.scxml2.SCXMLExecutionContext;
import org.apache.commons.scxml2.SCXMLExpressionException;
import org.apache.commons.scxml2.TriggerEvent;
import org.apache.commons.scxml2.semantics.ErrorConstants;

/**
 * The class in this SCXML object model that corresponds to the
 * &lt;final&gt; SCXML element.
 *
 * @since 0.7
 */
public class Final extends EnterableState {

    /**
     * Serial version UID.
     */
    private static final long serialVersionUID = 1L;

    private DoneData doneData;

    /**
     * Default no-args constructor.
     */
    public Final() {
    }

    /**
     * @return Returns the State parent
     */
    @Override
    public State getParent() {
        return (State)super.getParent();
    }

    /**
     * Set the parent State.
     * @param parent The parent state to set
     */
    public final void setParent(State parent) {
        super.setParent(parent);
    }

    /**
     * {@inheritDoc}
     * @return Returns always true (a state of type Final is always atomic)
     */
    public final boolean isAtomicState() {
        return true;
    }

    public DoneData getDoneData() {
        return doneData;
    }

    public void setDoneData(final DoneData doneData) {
        this.doneData = doneData;
    }

    public Object processDoneData(SCXMLExecutionContext exctx) throws ModelException {
        Object result = null;
        if (doneData != null) {
            try {
                Content content = doneData.getContent();
                Evaluator eval = exctx.getEvaluator();
                Context ctx = exctx.getScInstance().getGlobalContext();
                if (content != null) {
                    if (content.getExpr() != null) {
                        Object evalResult;
                        try {
                            evalResult = eval.eval(ctx, content.getExpr());
                        } catch (SCXMLExpressionException e) {
                            exctx.getInternalIOProcessor().addEvent(new EventBuilder(TriggerEvent.ERROR_EXECUTION,
                                    TriggerEvent.ERROR_EVENT).build());
                            exctx.getErrorReporter().onError(ErrorConstants.EXPRESSION_ERROR,
                                    "Failed to evaluate <donedata> <content> expression due to error: "+ e.getMessage()
                                            + ", Using empty value instead.", getParent());
                            evalResult = "";
                        }
                        result = eval.cloneData(evalResult);
                    } else if (content.getParsedValue() != null) {
                        result = eval.cloneData(content.getParsedValue().getValue());
                    }
                } else {
                    Map<String, Object> payloadDataMap = new LinkedHashMap<>();
                    PayloadBuilder.addParamsToPayload(exctx.getScInstance().getGlobalContext(),
                            exctx.getEvaluator(), doneData.getParams(), payloadDataMap);
                    if (!payloadDataMap.isEmpty()) {
                        result = payloadDataMap;
                    }
                }
            } catch (SCXMLExpressionException e) {
                result = null;
                exctx.getInternalIOProcessor().addEvent(new EventBuilder(TriggerEvent.ERROR_EXECUTION, TriggerEvent.ERROR_EVENT).build());
                exctx.getErrorReporter().onError(ErrorConstants.EXPRESSION_ERROR,
                        "Failed to process final donedata due to error: "+ e.getMessage(), getParent());
            }
        }
        return result;
    }
}

