package com.interpress_project.modernshare.serveradm;

import java.util.Properties;

import org.jacorb.sasPolicy.SASPolicyValues;
import org.jacorb.sasPolicy.SASPolicyValuesHelper;
import org.jacorb.sasPolicy.SAS_POLICY_TYPE;
import org.omg.CORBA.Any;
import org.omg.CORBA.ORB;
import org.omg.CORBA.Object;
import org.omg.CORBA.Policy;
import org.omg.CSIIOP.EstablishTrustInClient;
import org.omg.PortableServer.IdAssignmentPolicyValue;
import org.omg.PortableServer.LifespanPolicyValue;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.ThreadPolicyValue;

import com.interpress_project.modernshare.AppKeys;
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.orb.MdsClientInfoFactory;
import com.interpress_project.modernshare.orb.MdsServerInfoFactory;
import com.interpress_project.modernshare.orb.generated.MdsClientInfoHelper;
import com.interpress_project.modernshare.orb.generated.MdsServerInfoHelper;

/**
 * @stereotype Manager
 */
public class ORBManager extends Thread {
	private SystemBase sb = SystemBase.getInstance();
	/**
	 * @stereotype creates
	 */
	/*#com.interpress_project.modernshare.serveradm.SVNManagerImpl Dependency_Link*/

	/**
	 * @stereotype uses
	 */
	/*#com.interpress_project.modernshare.serveradm.ListGssUpContext Dependency_Link1*/

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

	private org.omg.CORBA_2_3.ORB orb;
	private POA poaRoot, poaFactory = null;
	private int processors = 0;
	private UserConfigDAO xmldao = null;

	/**
	 * ORBManager
	 * @param args
	 * @param acctmgr
	 * @param repmgr
	 */
	public ORBManager(String[] args, AccountManager acctmgr, SVNRepositoryManager repmgr) {
		propmgr = PropertyManager.getInstance();
		processors = Runtime.getRuntime().availableProcessors();

		/////////////////////////////////////////////////////
		// License check here.
//		LMManager lmmgr = LMManager.getInstance();
//		try {
//S			lmmgr.load(AppKeys.LICENSEFILE);
//		}
//		catch (LicenseCorruptException ex) {
//			// ここではメッセージを表示しない。
//			sb.getLogger().fatal("Server is forcely terminated.");
//			System.exit(-1);
//		}
//		entity = lmmgr.parse();
//		if (entity.isExpired()) {
//			String msg = "LICENSE EXPIRED " + entity.getExpire().toString() + "."
//			    + "You need to update license to continue to use HotShot.";
//			sb.getLogger().fatal(msg);
//			sb.getLogger().fatal("Server is forcely terminated.");
//			System.exit(-1);
//		}
//
//		if (entity.getLicType() == LicType.PERSONAL) {
//			if (acctmgr.getNumberOfAccounts() > 2) {
//				sb.getLogger().fatal(
//				  "The server run with Personal license. It can manager up to 2 accounts, including root account.");
//				sb.getLogger().fatal("Reduce account number by editing  " + propmgr.getSVNRootdir() + "/conf/passwd file.");
//				sb.getLogger().fatal("Server is forcely terminated.");
//				System.exit(-1);
//			}
//		}

//		if (processors > entity.getNumOfCPU()) {
//			sb.getLogger().fatal("FOUND SERVER HAS " + processors + " CPUs.");
//			sb.getLogger().fatal("YOUR LICENSE SUPPORTS UPTO " + entity.getNumOfCPU() + " CPUs.");
//			sb.getLogger().fatal("Server is forcely terminated.");
//			System.exit(-1);
//		}
		/////////////////////////////////////////////////////

		/**
		 * Initialize XML Dao.
		 */
		xmldao = new UserConfigDAO();

		Properties props = System.getProperties();
		props.setProperty("org.omg.CORBA.ORBClass", "org.jacorb.orb.ORB");
		props.setProperty("org.omg.CORBA.ORBSingletonClass", "org.jacorb.orb.ORBSingleton");

		props.setProperty("custom.props", AppKeys.ORBPropFilename);
		props.setProperty("jacorb.suppress_no_props_warning", "on");
		props.setProperty("jacorb.security.sas.contextClass",
		  "com.interpress_project.modernshare.serveradm.ListGssUpContext");
		props.setProperty("org.omg.PortableInterceptor.ORBInitializerClass.SAS", "org.jacorb.security.sas.SASInitializer");
		props.setProperty("org.omg.PortableInterceptor.ORBInitializerClass.GSSUPProvider",
		  "org.jacorb.security.sas.GSSUPProviderInitializer");

		props.setProperty("OAIAddr", propmgr.getServerName());
		props.setProperty("OASSLPort", propmgr.getAdminport());

		props.setProperty("jacorb.security.keystore", propmgr.getKeystore());
		props.setProperty("jacorb.security.keystore_password", propmgr.getKeystorePass());

		try {
			orb = (org.omg.CORBA_2_3.ORB) ORB.init(args, props);
			orb.register_value_factory(MdsServerInfoHelper.id(), new MdsServerInfoFactory());
			orb.register_value_factory(MdsClientInfoHelper.id(), new MdsClientInfoFactory());

			Object obj = orb.resolve_initial_references("RootPOA");
			poaRoot = POAHelper.narrow(obj);

			Any sasAny = orb.create_any();
			SASPolicyValuesHelper.insert(sasAny, new SASPolicyValues(EstablishTrustInClient.value,
			  EstablishTrustInClient.value, true));

			Policy[] MyServerFactoryPolicies = { poaRoot.create_lifespan_policy(LifespanPolicyValue.PERSISTENT),
			    poaRoot.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID),
			    poaRoot.create_thread_policy(ThreadPolicyValue.ORB_CTRL_MODEL),
			    orb.create_policy(SAS_POLICY_TYPE.value, sasAny) };

			poaFactory = poaRoot.create_POA("MyFactory_poa", poaRoot.the_POAManager(), MyServerFactoryPolicies);
			MdsServiceImpl servant = new MdsServiceImpl(orb, acctmgr, repmgr, xmldao);
			poaFactory.activate_object_with_id("MyFactory".getBytes(), servant);

			poaRoot.the_POAManager().activate();
		}
		catch (Exception ex) {
			ex.printStackTrace();
			sb.getLogger().fatal(ex.getMessage());
			sb.getLogger().fatal("Fail to start up ORB. Server is forcely terminated.");
			System.exit(-1);
		}
	}

	/**
	 * run
	 */
	public void run() {
//		sb.getLogger().info("License type : " + entity.getLicType().name());
		String actual = propmgr.getServerName();
		sb.getLogger().info("ORB hostname : " + actual);

		sb.getLogger().info("ORB Max CPU : " + processors);

		String virtual = propmgr.getVirtualServerName();
		if (!virtual.equalsIgnoreCase(actual)) {
			sb.getLogger().info("ORB Virtual host : " + virtual);
		}
		sb.getLogger().info("ORB port : " + propmgr.getAdminport());
		sb.getLogger().info("ORB started.");
		orb.run();
	}

	/**
	 * shutdown	 
	 */
	public void shutdown() {
		xmldao.dispose();

		orb.shutdown(false);
		orb = null;
	}
}
