/*
 * 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 freemarker.ext.jython;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.python.core.Py;
import org.python.core.PyDictionary;
import org.python.core.PyFloat;
import org.python.core.PyInteger;
import org.python.core.PyLong;
import org.python.core.PyNone;
import org.python.core.PyObject;
import org.python.core.PySequence;
import org.python.core.PyStringMap;

import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.DateModel;
import freemarker.ext.util.ModelCache;
import freemarker.template.TemplateModel;

class JythonModelCache extends ModelCache {
    private final JythonWrapper wrapper;
    
    JythonModelCache(JythonWrapper wrapper) {
        this.wrapper = wrapper;
    }

    @Override
    protected boolean isCacheable(Object object) {
        return true;
    }
    
    @Override
    protected TemplateModel create(Object obj) {
        boolean asHash = false;
        boolean asSequence = false;
        JythonVersionAdapter versionAdapter = JythonVersionAdapterHolder.INSTANCE;
        if (versionAdapter.isPyInstance(obj)) {
            Object jobj = versionAdapter.pyInstanceToJava(obj);
            // FreeMarker-aware, Jython-wrapped Java objects are left intact 
            if (jobj instanceof TemplateModel) {
                return (TemplateModel) jobj; 
            }
            if (jobj instanceof Map) {
                asHash = true;
            }
            if (jobj instanceof Date) {
                return new DateModel((Date) jobj, BeansWrapper.getDefaultInstance());
            } else if (jobj instanceof Collection) {
                asSequence = true;
                // FIXME: This is an ugly hack, but AFAIK, there's no better
                // solution if we want to have Sets and other non-List
                // collections managed by this layer, as Jython quite clearly
                // doesn't support sets.  
                if (!(jobj instanceof List)) {
                    obj = new ArrayList((Collection) jobj); 
                }
            }
        }
        
        // If it's not a PyObject, first make a PyObject out of it.
        if (!(obj instanceof PyObject)) {
            obj = Py.java2py(obj);
        }
        if (asHash || obj instanceof PyDictionary || obj instanceof PyStringMap) {
            return JythonHashModel.FACTORY.create(obj, wrapper);
        }
        if (asSequence || obj instanceof PySequence) {
            return JythonSequenceModel.FACTORY.create(obj, wrapper);
        }
        if (obj instanceof PyInteger || obj instanceof PyLong || obj instanceof PyFloat) {
            return JythonNumberModel.FACTORY.create(obj, wrapper);
        }
        if (obj instanceof PyNone) {
            return null;
        }
        return JythonModel.FACTORY.create(obj, wrapper);
    }
}
