/*
 * 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.tuscany.sca.databinding.sdo;

import java.lang.reflect.ParameterizedType;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection;

import javax.xml.namespace.QName;

import org.apache.tuscany.sca.databinding.WrapperHandler;
import org.apache.tuscany.sca.databinding.XMLTypeHelper;
import org.apache.tuscany.sca.databinding.impl.BaseDataBinding;
import org.apache.tuscany.sca.interfacedef.DataType;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.interfacedef.util.XMLType;
import org.apache.tuscany.sdo.api.SDOUtil;

import commonj.sdo.DataObject;
import commonj.sdo.Type;
import commonj.sdo.helper.CopyHelper;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.helper.XMLDocument;

/**
 * SDO Databinding
 * 
 * @version $Rev$ $Date$
 */
public class SDODataBinding extends BaseDataBinding {
    public static final String NAME = DataObject.class.getName();

    public static final String ROOT_NAMESPACE = "commonj.sdo";
    public static final QName ROOT_ELEMENT = new QName(ROOT_NAMESPACE, "dataObject");

    private WrapperHandler<Object> wrapperHandler;
    private XMLTypeHelper xmlTypeHelper;

    public SDODataBinding() {
        super(NAME, DataObject.class);
        wrapperHandler = new SDOWrapperHandler();
        xmlTypeHelper = new SDOTypeHelper();
    }

    @Override
    public boolean introspect(DataType dataType, final Operation operation) {
        Class javaType = dataType.getPhysical();
        // Allow privileged access to read system properties. Requires PropertyPermission
        // java.specification.version read in security policy.
        final HelperContext context = AccessController.doPrivileged(new PrivilegedAction<HelperContext>() {
            public HelperContext run() {
                return SDOContextHelper.getHelperContext(operation);
            }
        });

        final Type type = context.getTypeHelper().getType(javaType);
        if (type == null) {
            // FIXME: Need a better to test dynamic SDO
            // TUSCANY-3298: get underlying element type for collections
            boolean isMany = false;
            if (Collection.class.isAssignableFrom(javaType)) {
                java.lang.reflect.Type genericType = dataType.getGenericType();
                if (genericType instanceof ParameterizedType) {
                    java.lang.reflect.Type actualType = ((ParameterizedType)genericType).getActualTypeArguments()[0];
                    if (actualType instanceof Class) {
                        javaType = (Class)actualType;
                        isMany = true;
                    }
                }
            }
            if (DataObject.class.isAssignableFrom(javaType)) {
                // Dynamic SDO
                dataType.setDataBinding(getName());
                // TUSCANY-3298: use XMLType many value to indicate a collection
                Object logical = dataType.getLogical();
                if (logical == null) {
                    if (!isMany) {
                        dataType.setLogical(XMLType.UNKNOWN);
                    } else {
                        XMLType xmlType = new XMLType(null, null);
                        xmlType.setMany(true);
                        dataType.setLogical(xmlType);
                    }
                } else if (logical instanceof XMLType && isMany) {
                    ((XMLType)logical).setMany(true);
                }
                return true;
            }
            return false;
        } 
        if (type.isDataType()) {
            // FIXME: Ignore simple types?
            return false;
        }

        // Found a SDO type, replace the default context with a private one
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            public Object run() {
                if (context == SDOContextHelper.getDefaultHelperContext()) {
                    HelperContext newContext = SDOUtil.createHelperContext();
                    SDOContextHelper.register(newContext, type);
                    if (operation != null) {
                        operation.getInputType().setMetaData(HelperContext.class, newContext);
                    }
                } else {
                    SDOContextHelper.register(context, type);
                }
                return null;
            }
        });

        String namespace = type.getURI();
        String name = context.getXSDHelper().getLocalName(type);
        QName xmlType = new QName(namespace, name);
        dataType.setDataBinding(getName());
        QName elementName = null;
        Object logical = dataType.getLogical();
        if (logical instanceof XMLType) {
            elementName = ((XMLType)logical).getElementName();
        }
        dataType.setLogical(new XMLType(elementName, xmlType));

        return true;
    }

    @Override
    public WrapperHandler getWrapperHandler() {
        return wrapperHandler;
    }

    @Override
    public XMLTypeHelper getXMLTypeHelper() {
        // return new SDOTypeHelper();
        return xmlTypeHelper;
    }

    @Override
    public Object copy(Object arg, DataType dataType, Operation operation) {
        HelperContext context = SDOContextHelper.getHelperContext(operation);
        CopyHelper copyHelper = context.getCopyHelper();
        if (arg instanceof XMLDocument) {
            XMLDocument document = (XMLDocument)arg;
            DataObject dataObject = copyHelper.copy(document.getRootObject());
            return context.getXMLHelper().createDocument(dataObject,
                                                         document.getRootElementURI(),
                                                         document.getRootElementName());
        } else if (arg instanceof DataObject) {
            return context.getCopyHelper().copy((DataObject)arg);
        } else {
            return super.copy(arg, dataType, operation);
        }
    }

}
