package com.interpress_project.modernshare.serveradm;

import org.jacorb.security.sas.SASInitializer;
import org.omg.CORBA.Any;
import org.omg.CORBA_2_3.ORB;
import org.omg.PortableInterceptor.Current;

import com.interpress_project.modernshare.ipcommon.SystemBase;
import com.interpress_project.modernshare.model.AccountManager;
import com.interpress_project.modernshare.model.PropertyManager;
import com.interpress_project.modernshare.model.UserConfigDAO;
import com.interpress_project.modernshare.model.exceptions.AccountExistException;
import com.interpress_project.modernshare.model.exceptions.AccountNotExistException;
import com.interpress_project.modernshare.model.exceptions.LicenseException;
import com.interpress_project.modernshare.orb.MdsClientInfoImpl;
import com.interpress_project.modernshare.orb.generated.AccountExist;
import com.interpress_project.modernshare.orb.generated.AccountNotFound;
import com.interpress_project.modernshare.orb.generated.InternalError;
import com.interpress_project.modernshare.orb.generated.LicenseError;
import com.interpress_project.modernshare.orb.generated.MdsClientInfo;
import com.interpress_project.modernshare.orb.generated.MdsServerInfo;
import com.interpress_project.modernshare.orb.generated.MdsServicePOA;
import com.interpress_project.modernshare.orb.generated.NoPrivilege;
import com.interpress_project.modernshare.serveradm.exceptions.RepositoryException;

public class MdsServiceImpl extends MdsServicePOA {
	private SystemBase sb = SystemBase.getInstance();
	/**
	 * @stereotype uses
	 */
	/*#com.interpress_project.modernshare.serveradm.SVNClientManager Dependency_Link1*/

	/**
	 * @clientCardinality 1
	 * @supplierCardinality 0..1
	 */
	private PropertyManager propmgr;

	/**
	 * @clientCardinality 1
	 * @supplierCardinality 0..1
	 */
	private AccountManager acctmgr;

	/**
	 * @clientCardinality 1
	 * @supplierCardinality 0..1
	 */
	private SVNRepositoryManager repmgr;

	private ORB orb = null;
	private UserConfigDAO xmldao;

	/**
	 * SVNManagerImpl
	 * @param orb
	 * @param propmgr
	 * @param acctmgr
	 */
	public MdsServiceImpl(ORB orb, AccountManager acctmgr, SVNRepositoryManager repmgr, UserConfigDAO xmldao) {
		this.orb = orb;
		this.acctmgr = acctmgr;
		this.repmgr = repmgr;
		this.propmgr = PropertyManager.getInstance();

		this.xmldao = xmldao;
	}

	/**
	 * getCurrentAccount
	 * @return
	 */
	private String getCurrentAccount() {
		String accountName = null;
		try {
			Current current = (Current) orb.resolve_initial_references("PICurrent");
			Any anyName = current.get_slot(SASInitializer.sasPrincipalNamePIC);
			accountName = anyName.extract_string();
		}
		catch (Exception ex) {
			sb.getLogger().error("Exception accessing PICurrent: ", ex);
		}
		return accountName;
	}

	/**
	 * addUser
	 * @throws RepositoryNotExist 
	 */
	public void addUser(String account, String password) throws InternalError, NoPrivilege, AccountExist, LicenseError {
		sb.getLogger().info("Adding new account for " + account + " ...");

		/*
		 * Check root account.
		 */
		if (!getCurrentAccount().equals(propmgr.getAdministratorAccount())) {
			throw new NoPrivilege();
		}

		/**
		 * Make update to the password file.
		 */
		try {
			acctmgr.addUser(account, password);
		}
		catch (AccountExistException ex) {
			throw new AccountExist(ex.getLocalizedMessage());
		}
		catch (LicenseException ex) {
			throw new LicenseError();
		}
		sb.getLogger().info("Adding new account is successful.");
	}

	/**
	 * deleteUser
	 */
	public void deleteUser(String account) throws AccountNotFound, NoPrivilege {
		sb.getLogger().info("Deleting account for " + account + " ...");

		if (!getCurrentAccount().equals(propmgr.getAdministratorAccount())) {
			throw new NoPrivilege();
		}
		/**
		 * Make update to password file.
		 */
		try {
			acctmgr.deleteUser(account);
		}
		catch (AccountNotExistException ex) {
			throw new AccountNotFound(ex.getLocalizedMessage());
		}
		sb.getLogger().info("Deleting account is successful.");
	}

	/**
	 * getServerInfo
	 */
	public MdsServerInfo getServerInfo() {
//		String hostName = propmgr.getVirtualServerName(); // If Virtual host is not set, then it returns actual hostname.
//		int port = propmgr.getSVNServerPort();
//		LMManager lmmgr = LMManager.getInstance();
//		String name = propmgr.getAdministrator();
//		String email = propmgr.getAdministratorEmail();
//		LEntity entity = lmmgr.parse();
//		MdsServerInfo info = new MdsServerInfoImpl(hostName, port, name, email, entity.getLicType().name());
//		return info;
		// TODO
		return null;
	}

	/**
	 * changePassword
	 */
	public void changePassword(String account, String newpass) throws AccountNotFound {
		sb.getLogger().info("Changing password for " + account + " ...");

		try {
			acctmgr.changePassword(account, newpass);
		}
		catch (com.interpress_project.modernshare.model.exceptions.AccountNotExistException ex) {
			throw new AccountNotFound(ex.getMessage());
		}
		sb.getLogger().info("Changing password is successful.");
	}

	/**
	 * backup
	 */
	public String backup() throws InternalError, NoPrivilege {
		String dir = null;

		if (!getCurrentAccount().equals(propmgr.getAdministratorAccount())) {
			throw new NoPrivilege();
		}

		/**
		 * cleanup the repository.
		 */
		try {
			repmgr.cleanTransaction();
		}
		catch (RepositoryException e) {
		}

		try {
			dir = repmgr.backup();
		}
		catch (Throwable ex) {
			throw new InternalError(ex.getMessage());
		}
		return dir;
	}

	/**
	 * recovery
	 */
	public void recovery() throws InternalError, NoPrivilege {
		if (!getCurrentAccount().equals(propmgr.getAdministratorAccount())) {
			throw new NoPrivilege();
		}
		try {
			repmgr.cleanTransaction();
		}
		catch (RepositoryException ex) {
			throw new InternalError(ex.getCause().getMessage());
		}
	}

	/**
	 * getClientInfo
	 */
	public MdsClientInfo getClientInfo(String account, String clientid) {
		sb.getLogger().debug("Enter getClientInfo(" + account + ", " + clientid + ")");

		String xmldata = xmldao.find(account, clientid);
		if (xmldata == null) {
			xmldata = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><configure xmlns=\"http://www.interpress.co.jp/hotshot/client\"></configure>";
		}
		return new MdsClientInfoImpl(account, clientid, xmldata);
	}

	/**
	 * setClientInfo
	 */
	public void setClientInfo(MdsClientInfo info) {
		sb.getLogger().debug("Enter setClientInfo(" + info.getAccount() + ", " + info.getClientId() + ")");

		xmldao.add(info.getAccount(), info.getClientId(), info.getXMLdata());
		return;
	}
}
