/*
 * 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.ode.bpel.elang.xpath20.runtime;

import javax.xml.namespace.QName;
import javax.xml.xpath.XPathVariableResolver;

import net.sf.saxon.Configuration;
import net.sf.saxon.type.AtomicType;
import net.sf.saxon.type.SchemaType;
import net.sf.saxon.type.ValidationException;
import net.sf.saxon.value.AtomicValue;
import net.sf.saxon.value.EmptySequence;
import net.sf.saxon.value.StringValue;
import net.sf.saxon.value.Value;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.ode.bpel.common.FaultException;
import org.apache.ode.bpel.elang.xpath10.obj.OXPath10ExpressionBPEL20;
import org.apache.ode.bpel.elang.xpath20.compiler.WrappedResolverException;
import org.apache.ode.bpel.explang.EvaluationContext;
import org.apache.ode.bpel.obj.OLink;
import org.apache.ode.bpel.obj.OMessageVarType;
import org.apache.ode.bpel.obj.OScope;
import org.apache.ode.bpel.obj.OXsdTypeVarType;
import org.apache.ode.utils.DOMUtils;
import org.apache.ode.utils.Namespaces;
import org.w3c.dom.Node;

/**
 * @author mriou <mriou at apache dot org>
 */
public class JaxpVariableResolver implements XPathVariableResolver {

    private static final Logger __log = LoggerFactory.getLogger(JaxpVariableResolver.class);

    private EvaluationContext _ectx;
    private OXPath10ExpressionBPEL20 _oxpath;
    private Configuration _config;

    public JaxpVariableResolver(EvaluationContext ectx, OXPath10ExpressionBPEL20 oxpath, Configuration config) {
        _ectx = ectx;
        _oxpath = oxpath;
        _config = config;
    }

    public Object resolveVariable(QName variableName) {
        if (__log.isDebugEnabled()) {
            __log.debug("Resolving variable " + variableName);
        }

        if (!(_oxpath instanceof OXPath10ExpressionBPEL20)) {
            throw new IllegalStateException("XPath variables not supported for bpel 1.1");
        }

        // Custom variables
        if (variableName.getNamespaceURI().equals(Namespaces.ODE_EXTENSION_NS)) {
            if ("pid".equals(variableName.getLocalPart())) {
                return _ectx.getProcessId();
            } else if ("processQName".equals(variableName.getLocalPart())) {
                return _ectx.getProcessQName();
            }
            if ("currentEventDateTime".equals(variableName.getLocalPart())) {
                return _ectx.getCurrentEventDateTime();
            }
        }

        OXPath10ExpressionBPEL20 expr = _oxpath;
        if (expr.isIsJoinExpression()) {
            OLink olink = _oxpath.getLinks().get(variableName.getLocalPart());

            try {
                return _ectx.isLinkActive(olink) ? Boolean.TRUE : Boolean.FALSE;
            } catch (FaultException e) {
                throw new WrappedResolverException(e);
            }
        } else {
            String varName;
            String partName;
            int dotloc = variableName.getLocalPart().indexOf('.');
            if (dotloc == -1) {
                varName = variableName.getLocalPart();
                partName = null;
            } else {
                varName = variableName.getLocalPart().substring(0, dotloc);
                partName = variableName.getLocalPart().substring(dotloc + 1);
            }
            OScope.Variable variable = _oxpath.getVars().get(varName);
            OMessageVarType.Part part = partName == null ? null : ((OMessageVarType) variable.getType()).getParts().get(partName);

            try {
                final Node variableNode = _ectx.readVariable(variable, part);
                if (variableNode == null)
                    throw new FaultException(variable.getOwner().getConstants().getQnSelectionFailure(), "Unknown variable " + variableName.getLocalPart());
                if (_ectx.narrowTypes()) {
                    if (variable.getType() instanceof OXsdTypeVarType && ((OXsdTypeVarType) variable.getType()).isSimple())
                        return getSimpleContent(variableNode, ((OXsdTypeVarType) variable.getType()).getXsdType());
                    if (part != null && part.getType() instanceof OXsdTypeVarType && ((OXsdTypeVarType) part.getType()).isSimple())
                        return getSimpleContent(variableNode, ((OXsdTypeVarType) part.getType()).getXsdType());
                }

                // Saxon used to expect a node list, but now a regular node will suffice.
                return variableNode;
            } catch (FaultException e) {
                throw new WrappedResolverException(e);
            }
        }
    }

    public Value convertSimpleTypeToSaxon(QName type, String value) {
        int fp = _config.getNamePool().allocate("", type.getNamespaceURI(), type.getLocalPart());
        SchemaType type2 = _config.getSchemaType(fp);
        if (type2 == null || !type2.isAtomicType()) {
            __log.warn("Can't find simple type " + type + " value " + value + " result: " + null);
            return null;
        } else {
            try {
                AtomicValue value2 = StringValue.convertStringToAtomicType(value, (AtomicType) type2, null).asAtomic();
                if (__log.isDebugEnabled()) {
                    __log.debug("converting " + type + " value " + value + " result: " + value2);
                }
                return value2;
            } catch (ValidationException e) {
                __log.debug("Can't convert " + value + " to " + type + " returning empty sequence");
                return EmptySequence.getInstance();
            }
        }
    }

    public Object getSimpleContent(Node simpleNode, QName type) {
        String text = simpleNode.getTextContent();
        Object o = convertSimpleTypeToSaxon(type, text);
        if (__log.isDebugEnabled()) {
            __log.debug("getSimpleContent for " + DOMUtils.domToString(simpleNode) + " " + type + " returned " + o);
        }
        return o;
    }
}
