/*
 * 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.openjpa.jdbc.meta.strats;

import java.sql.SQLException;

import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.RelationId;
import org.apache.openjpa.jdbc.meta.ValueHandler;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.Row;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.InvalidStateException;

/**
 * Utility methods for strategies using value handlers.
 *
 * @author Abe White
 * @since 0.4.0
 */
public class HandlerStrategies {

    private static final Localizer _loc = Localizer.forPackage
        (HandlerStrategies.class);

    /**
     * Map the given value.
     */
    public static Column[] map(ValueMapping vm, String name, ColumnIO io,
        boolean adapt) {
        ValueMappingInfo vinfo = vm.getValueInfo();
        vinfo.assertNoJoin(vm, true);
        vinfo.assertNoForeignKey(vm, !adapt);

        DBDictionary dict = vm.getMappingRepository().getDBDictionary();
        DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
        Column[] cols = vm.getHandler().map(vm, colName.getName(), io, adapt);
        if (cols.length > 0 && cols[0].getTable() == null) {
            cols = vinfo.getColumns(vm, colName, cols,
                vm.getFieldMapping().getTable(), adapt);
            if (vinfo.isImplicitRelation())
            	for (int i = 0; i < cols.length; i++)
            		cols[i].setImplicitRelation(true);
            ColumnIO mappedIO = vinfo.getColumnIO();
            vm.setColumns(cols);
            vm.setColumnIO(mappedIO);
            if (mappedIO != null) {
                for (int i = 0; i < cols.length; i++) {
                    io.setInsertable(i, mappedIO.isInsertable(i, false));
                    io.setNullInsertable(i, mappedIO.isInsertable(i, true));
                    io.setUpdatable(i, mappedIO.isUpdatable(i, false));
                    io.setNullUpdatable(i, mappedIO.isUpdatable(i, true));
                }
            }
        }
        vm.mapConstraints(colName, adapt);
        return cols;
    }

    /**
     * Set the given value into the given row.
     * Return false if the given value can not be set, for example, due to
     * null constraints on the columns.
     */
    public static boolean set(ValueMapping vm, Object val, JDBCStore store,
        Row row, Column[] cols, ColumnIO io, boolean nullNone)
        throws SQLException {
        if (!canSetAny(row, io, cols))
            return false;

        ValueHandler handler = vm.getHandler();
        val = handler.toDataStoreValue(vm, val, store);
        boolean isSet = false;
        if (val == null) {
            for (int i = 0; i < cols.length; i++)
                if (canSet(row, io, i, true)) {
                    isSet = true;
                    set(row, cols[i], null, handler, nullNone);
                }
        } else if (cols.length == 1) {
            if (canSet(row, io, 0, val == null)) {
                isSet = true;
                set(row, cols[0], val, handler, nullNone);
            }
        } else {
            Object[] vals = (Object[]) val;
            for (int i = 0; i < vals.length; i++)
                if (canSet(row, io, i, vals[i] == null)) {
                    isSet = true;
                    set(row, cols[i], vals[i], handler, nullNone);
                }
        }
        return isSet;
    }

    /**
     * Return true if the given column index is settable.
     */
    private static boolean canSet(Row row, ColumnIO io, int i,
        boolean nullValue) {
        if (row.getAction() == Row.ACTION_INSERT)
        	return io.isInsertable(i, nullValue);
        if (row.getAction() == Row.ACTION_UPDATE)
        	return io.isUpdatable(i, nullValue);
        return true;
    }

    /**
     * Return true if the any column up to the given index is settable.
     */
    private static boolean canSetAny(Row row, ColumnIO io, Column[] cols) {
        if (row.getAction() == Row.ACTION_INSERT)
            return io.isAnyInsertable(cols, false);
        if (row.getAction() == Row.ACTION_UPDATE)
            return io.isAnyUpdatable(cols, false);
        return true;
    }

    /**
     * Set a value into a row, taking care not to override column defaults
     * with nulls unless the user wants us to.
     */
    private static void set(Row row, Column col, Object val,
        ValueHandler handler, boolean nullNone)
        throws SQLException {
        if (val == null)
            row.setNull(col, nullNone);
        else if (col.isRelationId() && handler instanceof RelationId)
            row.setRelationId(col, (OpenJPAStateManager) val,
                (RelationId) handler);
        else
            row.setObject(col, val);
    }

    /**
     * Add where conditions to the given row.
     */
    public static void where(ValueMapping vm, Object val, JDBCStore store,
        Row row, Column[] cols)
        throws SQLException {
        if (cols.length == 0)
            return;

        val = toDataStoreValue(vm, val, cols, store);
        if (val == null)
            for (int i = 0; i < cols.length; i++)
                row.whereNull(cols[i]);
        else if (cols.length == 1)
            where(row, cols[0], val);
        else {
            Object[] vals = (Object[]) val;
            for (int i = 0; i < vals.length; i++)
                where(row, cols[i], vals[i]);
        }
    }

    /**
     * Set a where condition on the given row.
     */
    private static void where(Row row, Column col, Object val)
        throws SQLException {
        if (val == null)
            row.whereNull(col);
        else
            row.whereObject(col, val);
    }

    /**
     * Load the Object value from the given result.
     */
    public static Object loadObject(ValueMapping vm, OpenJPAStateManager sm,
        JDBCStore store, JDBCFetchConfiguration fetch, Result res,
        Joins joins, Column[] cols, boolean objectValueRequiresLoad)
        throws SQLException {
        if (cols.length == 0)
            throw new InvalidStateException(_loc.get("cant-project-owned",
                vm));

        Object val = loadDataStore(vm, res, joins, cols);
        if (objectValueRequiresLoad)
            return vm.getHandler().toObjectValue(vm, val, sm, store, fetch);
        return vm.getHandler().toObjectValue(vm, val);
    }

    /**
     * Load the datastore value from the given result. This method does
     * <b>not</b> process the loaded value through
     * {@link ValueHandler#toObjectValue}.
     */
    public static Object loadDataStore(ValueMapping vm, Result res,
        Joins joins, Column[] cols)
        throws SQLException {
        if (cols.length == 0)
            return null;
        if (cols.length == 1)
            return res.getObject(cols[0], vm.getHandler().
                getResultArgument(vm), joins);

        Object[] vals = new Object[cols.length];
        Object[] args = (Object[]) vm.getHandler().getResultArgument(vm);
        for (int i = 0; i < cols.length; i++)
            vals[i] = res.getObject(cols[i], (args == null) ? null : args[i],
                joins);
        return vals;
    }

    /**
     * Convert the given object to its datastore value(s). Relation ids are
     * converted to their final values immediately.
     */
    public static Object toDataStoreValue(ValueMapping vm, Object val,
        Column[] cols, JDBCStore store) {
        ValueHandler handler = vm.getHandler();
        val = handler.toDataStoreValue(vm, val, store);
        if (val == null) {
            if (cols.length > 1)
                return new Object[cols.length];
            return null;
        }

        // relation ids are returned as state managers; resolve the final
        // datastore value immediately
        Object[] vals;
        for (int i = 0; i < cols.length; i++) {
            if (!cols[i].isRelationId())
                continue;
            if (!(handler instanceof RelationId))
                break;
            if (cols.length == 1) {
                val = ((RelationId) handler).toRelationDataStoreValue
                    ((OpenJPAStateManager) val, cols[i]);
            } else {
                vals = (Object[]) val;
                vals[i] = ((RelationId) handler).toRelationDataStoreValue
                    ((OpenJPAStateManager) vals[i], cols[i]);
            }
        }
        return val;
    }

    /**
     * Throw the proper exception if the given handler-controlled value
     * represents an unjoinable relation.
     */
    public static void assertJoinable(ValueMapping vm) {
        ClassMapping rel = vm.getTypeMapping();
        if (rel != null && (rel.getTable() == null
            || !rel.getTable().equals(vm.getFieldMapping().getTable())))
            throw RelationStrategies.unjoinable(vm);
    }
}
