package com.interpress_project.modernshare.client.controller.delegate;

import java.net.MalformedURLException;

import org.tigris.subversion.svnclientadapter.ISVNDirEntry;
import org.tigris.subversion.svnclientadapter.SVNClientException;
import org.tigris.subversion.svnclientadapter.SVNRevision;
import org.tigris.subversion.svnclientadapter.SVNUrl;

import com.interpress_project.modernshare.client.controller.delegate.exceptions.AccountExistException;
import com.interpress_project.modernshare.client.controller.delegate.exceptions.AccountNotFoundException;
import com.interpress_project.modernshare.client.controller.delegate.exceptions.InternalFailException;
import com.interpress_project.modernshare.client.controller.model.PropertyManager;

/**
 * Represents a singleton.
 * @stereotype Singleton factory
 */
public class AdminSVNManager extends ISVNManager {
	/**
	 * Holds singleton instance
	 */
	private static AdminSVNManager instance;

	/**
	 * AdminSVNManager
	 */
	public AdminSVNManager() {
	}

	public void createAccountArea(String account) throws InternalFailException, AccountExistException {
		existAccount(account);
		createSVNSpace(account);
	}

	private ISVNDirEntry[] getAccounts() throws InternalFailException {
		PropertyManager propmgr = PropertyManager.getInstance();
		String url = propmgr.getTargetSVNURL();
		SVNUrl svnurl;

		try {
			svnurl = new SVNUrl(url);
		}
		catch (MalformedURLException ex) {
			throw new InternalFailException("アドレス変換に失敗しました。(" + ex.getLocalizedMessage() + ")");
		}
		ISVNDirEntry[] entries = null;
		try {
			entries = svnClient.getList(svnurl, SVNRevision.HEAD, false);
		}
		catch (SVNClientException ex) {
			throw new InternalFailException("リストの取得に失敗しました。(" + ex.getLocalizedMessage() + ")");
		}
		return entries;
	}

	public void existAccount(String account) throws InternalFailException, AccountExistException {
		ISVNDirEntry[] accounts = getAccounts();
		for (int i = 0; i < accounts.length; i++) {
			String acct = accounts[i].getPath();
			if (acct.equalsIgnoreCase(account)) {
				throw new AccountExistException("既にアカウント" + account + "は存在しています。");
			}
		}
	}

	/**
	 * createSVNSpace
	 * @param account
	 * @throws InternalFailException
	 */
	public void createSVNSpace(String account) throws InternalFailException {
		PropertyManager propmgr = PropertyManager.getInstance();
		String url = propmgr.getTargetSVNURL(account);
		SVNUrl svnurl;

		try {
			svnurl = new SVNUrl(url);
		}
		catch (MalformedURLException ex) {
			throw new InternalFailException("アドレス変換に失敗しました。(" + ex.getLocalizedMessage() + ")");
		}
		try {
			svnClient.mkdir(svnurl, "Space for " + account);
		}
		catch (SVNClientException ex) {
			throw new InternalFailException("ユーザ領域の作成に失敗しました。(" + ex.getLocalizedMessage() + ")");
		}
	}

	/**
	 * deleteSVNSpace
	 * @param account
	 * @throws InternalFailException
	 */
	public void deleteSVNSpace(String account) throws InternalFailException {
		PropertyManager propmgr = PropertyManager.getInstance();
		String url = propmgr.getTargetSVNURL(account);
		SVNUrl svnurl;

		try {
			svnurl = new SVNUrl(url);
		}
		catch (MalformedURLException ex) {
			throw new InternalFailException("アドレス変換に失敗しました。(" + ex.getLocalizedMessage() + ")");
		}
		try {
			svnClient.remove(new SVNUrl[] { svnurl }, "");
		}
		catch (SVNClientException ex) {
			throw new InternalFailException("ユーザ領域の削除に失敗しました。(" + ex.getLocalizedMessage() + ")");
		}
	}

	/**
	 * deleteAccountArea
	 * @param account
	 * @throws InternalFailException
	 * @throws AccountNotFoundException
	 */
	public void deleteAccountArea(String account) throws InternalFailException, AccountNotFoundException {
		try {
			existAccount(account);
			throw new AccountNotFoundException();
		}
		catch (AccountExistException e) {
			// The account must be exist in remote! Fall down...
		}
		deleteSVNSpace(account);
	}

	/**
	 * Returns the singleton instance.
	 @return	the singleton instance
	 */
	static public AdminSVNManager getInstance() {
		if (instance == null) {
			instance = new AdminSVNManager();
		}
		return instance;
	}
}
