/*
 * 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.env;

import java.io.Serializable;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.scxml2.Context;

/**
 * A map that will back the effective {@link Context} for an {@link org.apache.commons.scxml2.Evaluator} execution.
 * The effective context enables the chaining of contexts all the way from the current state node to the root.
 */
public final class EffectiveContextMap extends AbstractMap<String, Object> implements Serializable {

    private static final long serialVersionUID = 1L;

    /** The {@link org.apache.commons.scxml2.Context} for the current state. */
    private final Context leaf;

    /**
     * Constructor.
     * @param ctx context of the current leave state node
     */
    public EffectiveContextMap(final Context ctx) {
        Context current = ctx;
        while (current != null) {
            if (current.getVars() instanceof EffectiveContextMap) {
                throw new IllegalArgumentException("Context or parent Context already wrapped by EffectiveContextMap");
            }
            current = current.getParent();
        }
        this.leaf = ctx;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Set<Entry<String, Object>> entrySet() {
        Map<String, Object> map = new HashMap<>();
        mergeVars(leaf, map);
        return Collections.unmodifiableMap(map).entrySet();
    }

    /**
     * Parent Context first merging of all Context vars, to ensure same named 'local' vars shadows parent var
     * @param leaf current leaf Context
     * @param map Map to merge vars into
     */
    protected void mergeVars(Context leaf, Map<String, Object> map) {
        if (leaf != null) {
            mergeVars(leaf.getParent(), map);
            map.putAll(leaf.getVars());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Object put(final String key, final Object value) {
        Object old = leaf.get(key);
        if (leaf.has(key)) {
            leaf.set(key, value);
        } else {
            leaf.setLocal(key, value);
        }
        return old;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Object get(final Object key) {
        if (key != null) {
            Context current = leaf;
            while (current != null) {
                if (current.getVars().containsKey(key.toString())) {
                    return current.getVars().get(key);
                }
                current = current.getParent();
            }
        }
        return null;
    }
}
