/*
 * blanco Framework
 * Copyright (C) 2004-2005 IGA Tosiki
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.db.expander.query;

import java.util.ArrayList;

import blanco.commons.util.BlancoJavaSourceUtil;
import blanco.db.util.BlancoDbQueryParserUtilDotNet;
import blanco.ig.expander.IgType;
import blanco.ig.expander.implementor.Implementor;
import blanco.ig.expander.method.MethodExpander;

/**
 * @author Yasuo Nakanishi
 */
public class GetQueryMethodDotNet extends MethodExpander {
    private String _query = "";

    public GetQueryMethodDotNet(final String query) {
        super("GetQuery");
        _query = query;
    }

    public void setupSignature() {
        // getQueryはpublicに変更。
        addUsingType(new IgType("System.String"));
        setReturnType(new IgType("string"));

        addUsingType(new IgType("System.Text.StringBuilder"));

        getJavaDoc().addLine("クエリの取得メソッド");
        getJavaDoc().addLine("実際に実行するSQL文を戻します。");
        getJavaDoc().addReturn("実際に実行されるSQL文");
    }

    public void implement() {
        final Implementor implementor = new Implementor(getData());

        // 2005.04.15 t.iga 改行は改行として出力するように変更。
        // 2005.10.12 t.iga blancoCommonsの変換ユーティリティを利用するように変更。
        final String escapedQuery = BlancoJavaSourceUtil
                .escapeStringAsJavaSource(_query);

        // クエリの #パラメータの?への変換。
        final String actualSql = new BlancoDbQueryParserUtilDotNet(escapedQuery)
                .getNaturalSqlStringForDotNet();

        // SQL文を改行の文字列で分断します。
        final String[] sqlLines = splitString(actualSql, "\\n");

        implementor.addLine("StringBuilder builder = new StringBuilder();");
        for (int index = 0; index < sqlLines.length; index++) {
            if (index == 0) {
                implementor.addLine("builder.Append(\"" + sqlLines[index]
                        + "\");");
            } else {
                implementor.addLine("builder.Append(\"" + sqlLines[index]
                        + "\");");
            }
        }

        implementor.addLine("return builder.ToString();");
    }

    /**
     * 与えられた文字列を指定の文字列を持って分割します。
     * 
     * このAPIでは、入力文字列から消えて失われる文字はありません。<br>
     * 共通関数化の候補API
     * 
     * @param originalString
     * @param delimiterString
     * @return
     */
    public static String[] splitString(final String originalString,
            final String delimiterString) {
        final ArrayList result = new ArrayList();
        String nextString = originalString;

        for (;;) {
            if (nextString.length() == 0) {
                break;
            }
            final int find = nextString.indexOf(delimiterString);
            if (find >= 0
                    && find + delimiterString.length() <= nextString.length()) {
                final String item = nextString.substring(0, find
                        + delimiterString.length());
                result.add(item);
                nextString = nextString.substring(find
                        + delimiterString.length());
            } else {
                result.add(nextString);
                break;
            }
        }

        final String[] resultStringArray = new String[result.size()];
        result.toArray(resultStringArray);
        return resultStringArray;
    }

}