/*
 * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
 *
 * http://izpack.org/
 * http://izpack.codehaus.org/
 *
 * Copyright 2004 Klaus Bartz
 *
 * 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 jp.co.ase.izpack.util;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

import com.izforge.izpack.installer.AutomatedInstallData;
import com.izforge.izpack.util.AbstractUIProcessHandler;

/**
 * Installer listener for reset the progress bar and initialize the simple
 * installer listener to support progress bar interaction. To support progress
 * bar interaction add this installer listener as first listener.
 *
 * @author Klaus Bartz
 */
public class RedmineLEUserInputParamCreator {

	public static final String SCRIPT_PATH = "/script/";

	public static final String PARAM_FILE_NAME = "userInputParam.txt";

	public static final String INSTALL_BATCH_FILE_NAME = "install.bat";

	/**
     *
     */
	public RedmineLEUserInputParamCreator() {
	}

	public void run(AbstractUIProcessHandler handler, String[] args) {
		AutomatedInstallData idata = AutomatedInstallData.getInstance();
		try {
			makeUserInputParameterFile(idata);
		} catch (Exception e) {
		}
	}

	/**
	 * make user input parameter file for ruby install batch
	 *
	 * @param idata
	 * @throws Exception
	 */
	private void makeUserInputParameterFile(AutomatedInstallData idata) throws Exception {
		String installPath = idata.getInstallPath();
		BufferedWriter writer = null;
		Writer fw = null;
		try {
			// charset UTF-8
			fw = new OutputStreamWriter(new FileOutputStream(installPath + SCRIPT_PATH
			        + PARAM_FILE_NAME), "UTF-8");
			writer = new BufferedWriter(fw);
			writer.write("apache_name: " + escapeYamlParameter(idata.getVariable("apache_name")));
			writer.newLine();
			writer.write("apache_port: " + idata.getVariable("apache_port"));
			writer.newLine();
			writer.write("redmine_name: " + escapeYamlParameter(idata.getVariable("redmine_name")));
			writer.newLine();
			writer.write("redmine_port: " + idata.getVariable("redmine_port"));
			writer.newLine();
			writer.write("hudson_name: " + escapeYamlParameter(idata.getVariable("hudson_name")));
			writer.newLine();
			writer.write("hudson_port: " + idata.getVariable("hudson_port"));
			writer.newLine();

			// LDAP
			// Use external LDAP server?
			String ldap_setting = idata.getVariable("ldap_setting");
			if ("0".equals(ldap_setting) || "false".equals(ldap_setting)) {
				writer.write("ldap_setting: " + "false");
				writer.newLine();
				writer.write("opends_name: "
				        + escapeYamlParameter(idata.getVariable("opends_name")));
				writer.newLine();
				writer.write("opends_port: " + idata.getVariable("opends_port"));
				writer.newLine();
				writer.write("opends_admin_port: " + idata.getVariable("opends_admin_port"));
				writer.newLine();
				writer.write("opends_base_dn: "
				        + escapeYamlParameter(idata.getVariable("opends_base_dn")));
				writer.newLine();
			} else {
				writer.write("ldap_setting: " + "true");
				writer.newLine();
				writer.write("ldap_host: " + escapeYamlParameter(idata.getVariable("ldap_host")));
				writer.newLine();
				writer.write("ldap_port: " + idata.getVariable("ldap_port"));
				writer.newLine();
				writer.write("ldap_base_dn: "
				        + escapeYamlParameter(idata.getVariable("ldap_base_dn")));
				writer.newLine();
				// ここだけrubyバッチの変数名と違っているので注意
				String ldap_bind_auth = idata.getVariable("ldap_anonymous");
				if ("true".equals(ldap_bind_auth) || "1".equals(ldap_bind_auth)) {
					// 匿名バインドが許可されていないのでBind認証情報を使う
					writer.write("ldap_anonymous: " + "false");
					writer.newLine();
					writer.write("ldap_bind_dn: "
					        + escapeYamlParameter(idata.getVariable("ldap_bind_dn")));
					writer.newLine();
					writer.write("ldap_bind_password: "
					        + escapeYamlParameter(idata.getVariable("ldap_bind_password")));
					writer.newLine();
				} else {
					writer.write("ldap_anonymous: " + "true");
					writer.newLine();
				}
				writer.write("ldap_user_attribute: "
				        + escapeYamlParameter(idata.getVariable("ldap_user_attribute")));
				writer.newLine();
				writer.write("ldap_first_name_attribute: "
				        + escapeYamlParameter(idata.getVariable("ldap_first_name_attribute")));
				writer.newLine();
				writer.write("ldap_last_name_attribute: "
				        + escapeYamlParameter(idata.getVariable("ldap_last_name_attribute")));
				writer.newLine();
				writer.write("ldap_mail_attribute: "
				        + escapeYamlParameter(idata.getVariable("ldap_mail_attribute")));
				writer.newLine();
			}

			// admin account
			writer.write("admin_account: "
			        + escapeYamlParameter(idata.getVariable("admin_account")));
			writer.newLine();
			writer.write("admin_password: "
			        + escapeYamlParameter(idata.getVariable("admin_password")));
			writer.newLine();
			// 外部LDAPを使用するが、メール・苗字・名前属性のいずれかが見つからなかったどうかフラグ
			String displayMailSnGivenNameLdapSetting = idata
			        .getVariable("displayMailSnGivenNameLdapSetting");
			if ("0".equals(ldap_setting) || "false".equals(ldap_setting)) {
				// 外部LDAPを使用しない場合
				writer.write("admin_mail: " + escapeYamlParameter(idata.getVariable("admin_mail")));
				writer.newLine();
				writer.write("admin_first_name: "
				        + escapeYamlParameter(idata.getVariable("admin_first_name")));
				writer.newLine();
				writer.write("admin_last_name: "
				        + escapeYamlParameter(idata.getVariable("admin_last_name")));
				writer.newLine();
			} else if ("true".equals(displayMailSnGivenNameLdapSetting)) {
				String notExistsLdapMail = idata.getVariable("notExistsLdapMail");
				if ("true".equals(notExistsLdapMail)) {
					writer.write("admin_mail: "
					        + escapeYamlParameter(idata.getVariable("admin_mail")));
					writer.newLine();
				}
				String notExistsLdapSn = idata.getVariable("notExistsLdapSn");
				if ("true".equals(notExistsLdapSn)) {
					writer.write("admin_last_name: "
					        + escapeYamlParameter(idata.getVariable("admin_last_name")));
					writer.newLine();
				}
				String notExistsLdapGivenName = idata.getVariable("notExistsLdapGivenName");
				if ("true".equals(notExistsLdapGivenName)) {
					writer.write("admin_first_name: "
					        + escapeYamlParameter(idata.getVariable("admin_first_name")));
					writer.newLine();
				}
			}

			// MAIL
			String smtp_setting = idata.getVariable("smtp_setting");
			if ("true".equals(smtp_setting) || "1".equals(smtp_setting)) {
				writer.write("smtp_setting: " + "true");
				writer.newLine();
				writer.write("mail_sender_address: "
				        + escapeYamlParameter(idata.getVariable("mail_sender_address")));
				writer.newLine();
				writer.write("smtp_host: " + escapeYamlParameter(idata.getVariable("smtp_host")));
				writer.newLine();
				writer.write("smtp_port: " + idata.getVariable("smtp_port"));
				writer.newLine();

				String smtp_auth = idata.getVariable("smtp_auth");
				if ("true".equals(smtp_auth) || "1".equals(smtp_auth)) {
					// SMTP Auth
					writer.write("smtp_auth: " + "true");
					writer.newLine();
					writer.write("smtp_user: "
					        + escapeYamlParameter(idata.getVariable("smtp_user")));
					writer.newLine();
					writer.write("smtp_password: "
					        + escapeYamlParameter(idata.getVariable("smtp_password")));
					writer.newLine();
				}
			} else {
				writer.write("smtp_setting: " + "false");
				writer.newLine();
			}

		} catch (Exception e) {
			throw e;
		} finally {
			try {
				if (writer != null) {
					writer.close();
				}
			} catch (Exception e) {
				throw e;
			}
		}
	}

	/**
	 * 文字列をダブルクォートで囲み、ダブルクォートとバックスラッシュをバックスラッシュでエスケープする
	 *
	 * @param value
	 * @return
	 * @throws Exception
	 */
	private String escapeYamlParameter(String value) throws Exception {
		String quote = "\"";
		// バックスラッシュをエスケープ
		value = value.replaceAll("\\\\", "\\\\\\\\");
		// value = value.replaceAll(":", "\\\\:");
		// ダブルクォートをエスケープ
		value = value.replaceAll(quote, "\\\\\"");
		// クォートで囲む
		value = stringPadFrontAndRear(quote, value);
		return value;
	}

    /**
     * padStringでvalueの前後を囲んで返却する
     * @param padString
     * @param value
     * @return
     */
    private String stringPadFrontAndRear(String padString, String value)
    {
    	StringBuffer buf = new StringBuffer(padString);
		buf.append(value);
		buf.append(padString);
		return buf.toString();
    }
}
