/*
 * Copyright 2004-2010 the Seasar Foundation and the Others.
 *
 * Licensed 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.seasar.codegen.dbms;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;
import org.seasar.codegen.element.DataType;
import org.seasar.codegen.element.FieldSetting;
import org.seasar.codegen.impl.JavaDataTypeSelectHelperImpl;
import org.seasar.codegen.unit.util.AssertUtil;
import org.seasar.codegen.unit.util.CSVUtil;
import org.seasar.codegen.unit.util.FieldSettingUtil;
import org.seasar.framework.beans.factory.BeanDescFactory;

public abstract class AbstractDbmsTestCase {

    protected static final Map<String, String> classNameMapping;

    static {
        classNameMapping = new HashMap<String, String>();
        classNameMapping.put("Timestamp", "java.sql.Timestamp");
        classNameMapping.put("Date", "java.util.Date");
        classNameMapping.put("BigDecimal", "java.math.BigDecimal");
        classNameMapping.put("Time", "java.sql.Time");

    }

    protected Dbms target;

    protected FieldSetting fieldSetting;

    protected String expectClassName;

    public AbstractDbmsTestCase(FieldSetting fieldSetting,
            String expectClassName) {
        super();
        this.fieldSetting = fieldSetting;
        this.expectClassName = expectClassName;
    }

    @Before
    public void setUp() throws Exception {
        target = createDbmsInstance();
        injectLangSelectUtil(target);
    }

    protected abstract Dbms createDbmsInstance();

    protected void injectLangSelectUtil(Dbms dbms)
            throws IllegalAccessException, InvocationTargetException {
        BeanDescFactory.getBeanDesc(dbms.getClass())
                .getPropertyDesc("langSelectUtil")
                .setValue(dbms, new JavaDataTypeSelectHelperImpl());
    }

    @Test
    public void doTest() {
        DataType type = target.selectBestDataType(fieldSetting);
        AssertUtil.assertDataType(fieldSetting.getTypeName(), expectClassName,
                type);
    }

    protected static String getClassName(String name) {
        String result = classNameMapping.get(name);
        if (result != null) {
            return result;
        } else {
            return name;
        }

    }

    protected static List<String[]> readCSV(String dbms) {
        return CSVUtil.readCSV("org/seasar/codegen/dbms/" + dbms + ".csv");
    }

    protected static List<Object[]> createParameter(List<String[]> parameters) {
        List<Object[]> ret = new ArrayList<Object[]>();

        for (String[] strings : parameters) {
            ret.add(new Object[] {
                    FieldSettingUtil.createFieldSetting(strings[0], strings[1]),
                    getClassName(strings[2]) });
        }

        return ret;
    }
}
