/*
 * 作成日: 2008/08/05
 * 著作権: Copyright (c) 2005 ZIGEN
 * ライセンス：Eclipse Public License - v 1.0
 * 原文：http://www.eclipse.org/legal/epl-v10.html
 */
package zigen.plugin.db.ext.s2jdbc.service;

import zigen.plugin.db.core.TableColumn;
import zigen.plugin.db.core.TablePKColumn;
import zigen.plugin.db.ext.s2jdbc.CodeGenerator;
import zigen.plugin.db.ext.s2jdbc.entity.rule.DefaultEntityMappingFactory;
import zigen.plugin.db.ext.s2jdbc.entity.rule.IEntityMappingFactory;
import zigen.plugin.db.ext.s2jdbc.util.PropertyNameUtil;
import zigen.plugin.db.ui.internal.Column;
import zigen.plugin.db.ui.internal.ITable;
import zigen.plugin.db.ui.internal.TreeLeaf;

public class ServiceGenerator extends CodeGenerator {

    private String prefix = "Service"; //$NON-NLS-1$

    private ITable table;

    private TreeLeaf[] leafs;

    boolean underLineCut = true;

    String accessModifiers = "public"; // 初期値 public //$NON-NLS-1$

    IEntityMappingFactory mapping;

    private String rootPackageName;

    public ServiceGenerator(ITable table, String rootPackageName) {
        this.table = table;
        this.leafs = table.getChildrens();
        this.mapping = DefaultEntityMappingFactory.getFactory(table.getDbConfig());
        this.rootPackageName = rootPackageName;
    }

    private void do_import() {
        println("import org.seasar.extension.jdbc.service.S2AbstractService;");
        println("import " + rootPackageName + ".entity." + getEntityName() + ";");
        println();
    }

    private void do_classBegin() {
        println("public class " + getClassName() + " extends S2AbstractService<" + getEntityName() + ">{"); //$NON-NLS-1$ //$NON-NLS-2$
        println();

    }

    private void do_classEnd() {
        println("}"); //$NON-NLS-1$
    }

    public void execute() {
        super.setGenerateInfo();
        do_import();
        super.setClassComment();
        do_classBegin();
        do_method();
        do_classEnd();
    }

    public String getClassName() {
        StringBuffer sb = new StringBuffer();
        sb.append(getEntityName());
        sb.append(prefix); // prefix(VO)
        return sb.toString();
    }

    public String getEntityName() {
        String str = table.getName();
        StringBuffer sb = new StringBuffer();
        sb.append(str.substring(0, 1).toUpperCase());
        sb.append(str.substring(1, str.length()).toLowerCase());
        return sb.toString();
    }

    private void do_toString() {
        String[] properties = new String[leafs.length];
        for (int i = 0; i < leafs.length; i++) {
            Column col = (Column) leafs[i];
            properties[i] = PropertyNameUtil.getProperty(col, underLineCut);
        }
        println(toStringString(getClassName(), properties));
    }

    private String getJavaType(Column col) {
        TableColumn tCol = col.getColumn();
        return mapping.getJavaType(tCol);
    }

    private boolean hasPrimaryKey() {
        for (int i = 0; i < leafs.length; i++) {
            Column col = (Column) leafs[i];
            TablePKColumn pkColumn = col.getPkColumn();
            if (pkColumn != null) {
                return true;
            }
        }
        return false;
    }

    // プロパティ定義
    private void do_method() {

        if (hasPrimaryKey()) {

            println("\t/**"); //$NON-NLS-1$
            println("\t * FindByPrimaryKey"); //$NON-NLS-1$
            println("\t */"); //$NON-NLS-1$

            StringBuffer sb = new StringBuffer();
            println("\tpublic " + getEntityName() + " findByPrimaryKey(" + getPrimaryKeyString() + ") {");
            println("\t\treturn select().id(" + getPrimaryKeyString2() + ").getSingleResult();");
            println("\t}");

        }

    }

    protected String getPrimaryKeyString() {
        StringBuffer sb = new StringBuffer();
        int pkCount = 0;
        for (int i = 0; i < leafs.length; i++) {
            Column col = (Column) leafs[i];
            TableColumn tCol = col.getColumn();
            TablePKColumn pkColumn = col.getPkColumn();
            String type = mapping.getJavaType(tCol);
            String property = tCol.getColumnName().toLowerCase();
            if (pkColumn != null) {
                if (pkCount == 0) {
                    sb.append(type + " " + property);
                } else {
                    sb.append(", " + type + " " + property);
                }
                pkCount++;
            }
        }
        return sb.toString();
    }

    protected String getPrimaryKeyString2() {
        StringBuffer sb = new StringBuffer();
        int pkCount = 0;
        for (int i = 0; i < leafs.length; i++) {
            Column col = (Column) leafs[i];
            TableColumn tCol = col.getColumn();
            TablePKColumn pkColumn = col.getPkColumn();
            String type = mapping.getJavaType(tCol);
            String property = tCol.getColumnName().toLowerCase();
            if (pkColumn != null) {
                if (pkCount == 0) {
                    sb.append(property);
                } else {
                    sb.append(", " + property);
                }
                pkCount++;
            }
        }
        return sb.toString();
    }
}
