package charactermanaj.util;

import java.io.File;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;

/**
 * アプリケーションの設定ファイル等の位置を取得するユーテリティクラス.<br>
 * Mainクラスのロード時に最も早くロードされるであろうクラスの一つである.<br>
 * @author seraphy
 */
public final class ConfigurationDirUtilities {

	public static final String CONFIGURATION_DIR_NAME = ".charactermanaj";

	private static File userDataDir;
	
	private static File applicationBaseDir;
	
	private ConfigurationDirUtilities() {
		throw new RuntimeException("utilities class.");
	}
	
	/**
	 * ユーザーごとのアプリケーションデータ保存先を取得する.<br>
	 * 環境変数「APPDATA」があれば、それをベースにする.<br>
	 * なければ、システムプロパティの「APPDATA」をベースにする.<br>
	 * それもなければ、システムプロパティの「user.home」をベースにする.<br>
	 * このベース位置に対して「.charactermanaj」という名前のディレクトリを、
	 * ユーザーごとのアプリケーションデータの保存先とする.<br>
	 */
	public static File getUserDataDir() {
		if (userDataDir == null) {
			
			String appData = null;
			try {
				// システムプロパティ「APPDATA」を探す
				appData = System.getProperty("APPDATA");
				if (appData == null) {
				}
				// なければ環境変数APPDATAを探す
				// Windows2000/XP/Vista/Windows7には存在する.
				appData = System.getenv("APPDATA");
				
			} catch (SecurityException e) {
				// 無視する.
			}
			
			if (appData == null) {
				// なければシステムプロパティ「user.home」を使う
				// このプロパティは必ず存在する
				appData = System.getProperty("user.home");
			}
			
			// ディレクトリ名は「.」で始まることで、MacOSX/Linux上で不可視フォルダにする。
			userDataDir = new File(appData, CONFIGURATION_DIR_NAME).getAbsoluteFile();

			// ディレクトリを準備する.
			userDataDir.mkdirs();
		}
		return userDataDir;
	}

	/**
	 * アプリケーションディレクトリを取得する.<br>
	 * このクラスをコードソースから、ベースとなる位置を割り出す.<br>
	 * クラスが格納されているクラスパスのフォルダか、JARに固められている場合は、そのJARファイルの、その親ディレクトリを指し示す.<br>
	 * このクラスのプロテクションドメインのコードソースがnullでコードの位置が取得できないか、
	 * コードの位置を示すURLがファイルプロトコルでない場合は実行時例外が返される.<br>
	 */
	public static File getApplicationBaseDir() {
		if (applicationBaseDir == null) {
			ProtectionDomain pdomain = ConfigurationDirUtilities.class.getProtectionDomain();

			CodeSource codeSource = pdomain.getCodeSource();
			if (codeSource == null) {
				throw new RuntimeException("codeSource is null: domain=" + pdomain);
			}
			
			URL codeBaseUrl = codeSource.getLocation();
			if (!codeBaseUrl.getProtocol().equals("file")) {
				throw new RuntimeException("codeLocation is not file protocol.: " + codeBaseUrl);
			}
			
			// クラスパスフォルダ、またはJARファイルの、その親
			applicationBaseDir = new File(codeBaseUrl.getPath()).getParentFile();
		}
		return applicationBaseDir;
	}
	
}
