/*
 * Copyright (c) 2005- Shinji Kashihara.
 * All rights reserved. This program are made available under
 * the terms of the Eclipse Public License v1.0 which accompanies
 * this distribution, and is available at epl-v10.html.
 */
package jp.sourceforge.mergedoc.pleiades.runtime;

import java.io.File;
import java.io.IOException;

import javassist.NotFoundException;
import jp.sourceforge.mergedoc.pleiades.Pleiades;
import jp.sourceforge.mergedoc.pleiades.PleiadesOption;
import jp.sourceforge.mergedoc.pleiades.log.Logger;
import jp.sourceforge.mergedoc.pleiades.resource.Files;

/**
 * IDEA 起動時のバイトコード変換を行うトランスフォーマーです。
 * <p>
 * @author cypher256
 */
public class LauncherIdeaTransformer extends LauncherTransformer {

	/** ロガー */
	private static final Logger log = Logger.getLogger(LauncherIdeaTransformer.class);

	/**
	 * 初期処理を行います。
	 */
	@Override
	protected void init() {

		long start = System.nanoTime();

		// IDEA 系のクラスパスに必ず含まれている jar から lib ディレクトリーを解決
		final String jarFileName = "bootstrap.jar";
		String jarPath = null;
		for (String path : System.getProperty("java.class.path").split(File.pathSeparator)) {
			if (path.endsWith(jarFileName)) {
				jarPath = path;
				break;
			}
		}
		if (jarPath == null) {
			throw new IllegalStateException(jarFileName + " が見つからないため lib ディレクトリーを特定できません。");
		}
		final File lib = new File(jarPath).getParentFile();

		// Javassist クラスパスに jar を追加 : 非同期実行 (待ち無し)
		AsyncQueue.add(new AsyncCommand("IDEA lib の jar を AOP クラスパスへ追加") {
			public void execute() throws Exception {

				// lib/*.jar 追加 (idea.jar は phpstorm.jar など製品ごとに異なる)
				for (File jar : lib.listFiles(Files.createSuffixFilter(".jar"))) {
					addClassPath(jar);
				}

				// 存在する場合のみ追加する jar (IDEA Ultimate では一部のみ存在する場合がある)
				File plugins = new File(lib.getParentFile(), "plugins");
				addClassPathExists(new File(plugins, "android/lib/android.jar"));
				addClassPathExists(new File(plugins, "android/lib/sdk-tools.jar"));
				addClassPathExists(new File(plugins, "sdk-updates/lib/sdk-updates.jar"));
			}
		});

		// 更新チェック : 非同期実行 (待ち有り) -clean 設定
		final PleiadesOption option = Pleiades.getPleiadesOption();
		if (!option.isClean) {
			AsyncQueue.addAwait(new AsyncCommand("IDEA 最終更新時刻の判定") {
				public void execute() throws Exception {

					if (Applications.isUpdated(lib)) {
						option.isClean = true;
						log.info("IDEA の更新が検出されたため、強制的に -clean モードで起動します。");
					}
				}
			});
		}

		super.init();
		Analyses.end(LauncherIdeaTransformer.class, "init", start);
	}

	/**
	 * Javassist クラスパスに jar ファイルを追加します。
	 * <ul>
	 * <li>ファイルが存在しない場合は追加しません。
	 * </ul>
	 * @param jarFile jar ファイル
	 */
	protected void addClassPathExists(File jarFile) throws IOException, NotFoundException {

		if (jarFile.exists()) {
			log.info("追加クラスパスあり: " + jarFile.getPath());
			addClassPath(jarFile);
		} else {
			log.info("追加クラスパスなし: " + jarFile.getPath());
		}
	}
}
