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

import groovy.lang.Closure;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.scxml2.Context;
import org.apache.commons.scxml2.SCInstanceObjectInputStream;
import org.apache.commons.scxml2.env.SimpleContext;

/**
 * Groovy Context implementation for Commons SCXML.
 */
public class GroovyContext extends SimpleContext {

    private static final long serialVersionUID = 1L;

    private static final Log log = LogFactory.getLog(GroovyContext.class);

    private String scriptBaseClass;
    private GroovyEvaluator evaluator;
    private GroovyContextBinding binding;
    private Map<String, Object> vars;

    GroovyContextBinding getBinding() {
        if (binding == null) {
            binding = new GroovyContextBinding(this);
        }
        return  binding;
    }

    /**
     * Constructor.
     */
    public GroovyContext() {
        super();
    }

    /**
     * Constructor with initial vars.
     *
     * @param parent The parent context.
     * @param initialVars The initial set of variables.
     * @param evaluator The groovy evaluator
     */
    public GroovyContext(final Context parent, final Map<String, Object> initialVars, GroovyEvaluator evaluator) {
        super(parent, initialVars);
        this.evaluator = evaluator;
    }

    /**
     * Constructor with parent context.
     *
     * @param parent The parent context.
     * @param evaluator The groovy evaluator
     */
    public GroovyContext(final Context parent, GroovyEvaluator evaluator) {
        super(parent);
        this.evaluator = evaluator;
    }

    protected GroovyEvaluator getGroovyEvaluator() {
        return evaluator;
    }

    protected void setGroovyEvaluator(GroovyEvaluator evaluator) {
        this.evaluator = evaluator;
    }

    @Override
    public Map<String, Object> getVars() {
        return vars;
    }

    @Override
    protected void setVars(final Map<String, Object> vars) {
        this.vars = vars;
    }

    protected void setScriptBaseClass(String scriptBaseClass) {
        this.scriptBaseClass = scriptBaseClass;
    }

    protected String getScriptBaseClass() {
        if (scriptBaseClass != null) {
            return scriptBaseClass;
        }
        if (getParent() instanceof GroovyContext) {
            return ((GroovyContext)getParent()).getScriptBaseClass();
        }
        return null;
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        boolean closureErased = false;
        if (vars != null) {
            Iterator<Map.Entry<String, Object>> iterator = getVars().entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Object> entry = iterator.next();
                if (entry.getValue() != null && entry.getValue() instanceof Closure) {
                    iterator.remove();
                    closureErased = true;
                }
            }
            if (closureErased) {
                log.warn("Encountered and removed Groovy Closure(s) in the GroovyContext during serialization: these are not supported for (de)serialization");
            }
        }
        out.writeObject(this.scriptBaseClass);
        out.writeObject(this.evaluator);
        out.writeObject(this.binding);
        out.writeObject(this.vars);
    }

    @SuppressWarnings("unchecked")
    private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {
        this.scriptBaseClass = (String)in.readObject();
        this.evaluator = (GroovyEvaluator)in.readObject();
        this.binding = (GroovyContextBinding)in.readObject();
        SCInstanceObjectInputStream.ClassResolver currentResolver = null;
        try {
            if (evaluator != null && in instanceof SCInstanceObjectInputStream) {
                currentResolver = ((SCInstanceObjectInputStream)in).setClassResolver(osc -> Class.forName(osc.getName(), true, evaluator.getGroovyClassLoader()));
            }
            this.vars = (Map<String, Object>)in.readObject();
        }
        finally {
            if (in instanceof SCInstanceObjectInputStream) {
                ((SCInstanceObjectInputStream)in).setClassResolver(currentResolver);
            }
        }
    }
}
