using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using com.plumtree.server;
using System.Configuration;

namespace bulkusers
{
	/// <summary>
	/// Summary description for WebForm1.
	/// </summary>
	public partial class index : System.Web.UI.Page
	{
		protected IPTObjectManager om;
		protected IPTQueryResult qr;

		protected void Page_Load(object sender, System.EventArgs e)
		{
			// put out a stylesheet for style
			Response.Write("<style>body,p,td { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt}</style>");

			// create a session to portal and connect
			string sAdminName = ConfigurationSettings.AppSettings["admin-name"];
			string sAdminPass = ConfigurationSettings.AppSettings["admin-pass"];
			string sPTHome = ConfigurationSettings.AppSettings["pthome"] + "";
			com.plumtree.openkernel.config.IOKContext context = com.plumtree.openkernel.factory.OKConfigFactory.createInstance( sPTHome + "\\settings", "portal");
			PortalObjectsFactory.Init(context);
			IPTSession session = PortalObjectsFactory.CreateSession();
			try 
			{
				session.Connect(sAdminName,sAdminPass,null);
			} 
			catch (Exception ex)
			{
				Response.Write("<p>Sorry. I couldn't connect as the user " + sAdminName + ". Does that user really exist? Did you put the proper password into web.config?");
				Response.Write("<p>More error information is in the HTML comments.\n\n");
				Response.Write("<!--\n\n" + ex.Message + "\n\n" + ex.StackTrace + "\n\n-->");
				Response.End();
			}

			// you'll add user to groups. get groups from web.config as a string array
			string sGroups = ConfigurationSettings.AppSettings["user-default-groups"];
			string[] groups = sGroups.Split(",".ToCharArray());

			// get values used in creating user
			int iDestinationFolder = System.Convert.ToInt16(ConfigurationSettings.AppSettings["user-destination-folder"]);
			string sDestinationFolderName = ConfigurationSettings.AppSettings["user-destination-folder-name"];
			string sDestinationFolderNameFromAPI = "";
			try 
			{
				sDestinationFolderNameFromAPI = session.GetAdminCatalog().OpenAdminFolder(iDestinationFolder,false).GetName();
			} 
			catch (Exception ex)
			{
				Response.Write("<p>Sorry. I couldn't get the name of the folder whose object id is in web.config, " + iDestinationFolder + ". Does that folder really exist? Does the user this web application connects with have access to that folder?");
				Response.Write("<p>More error information is in the HTML comments.\n\n");
				Response.Write("<!--\n\n" + ex.Message + "\n\n" + ex.StackTrace + "\n\n-->");
				Response.End();
			}
			bool bFolderIDMatchesFolderName = (sDestinationFolderName.ToLower() == sDestinationFolderNameFromAPI.ToLower()) ? true : false;

			int iNewUserID=0;			
			string sNewUserPass = ConfigurationSettings.AppSettings["new-user-password"];
			
			if (!bFolderIDMatchesFolderName) 
			{
				Response.Write("<p>Sorry. It looks like you haven't set web.config properly. The object id for the folder you want to put users in (user-destination-folder) must correspond to the name of that folder (user-destination-folder-name).");
				Response.Write("<p>sDestinationFolderName is " + sDestinationFolderName);
				Response.Write("<p>sDestinationFolderNameFromAPI is " + sDestinationFolderNameFromAPI);
				// PTDebug.Trace(com.plumtree.debug.Component.WebServicesSessionAPI, TraceType.Warn , "web.config's values for the name and objectid to put users into do not match.");
			}
			else
			{
				string sAction = Request.QueryString["action"];
				if (sAction == "create")
				{
					string sCount = Request.QueryString["count"];
					if (sCount == null || sCount.Length == 0) 
					{
						Response.Write("You need to indicate how many users you want to create through the 'count' parameter.");
					} 
					else 
					{
						int iCount = Convert.ToInt32(sCount);
						string sNewUserName = "";
						// create a bunch of groups
						for (int i=0; i<iCount; i++) 
						{
							iNewUserID = CreateUser("bulkuser" + System.DateTime.Now.ToShortTimeString() + "-" + i.ToString(),sNewUserPass,iDestinationFolder, session);
							sNewUserName = "bulkuser" + iNewUserID.ToString();
							ChangeUserName(iNewUserID,sNewUserName,session);
							if ( AddUserToGroups(iNewUserID, groups, session) ) 
							{
								Response.Write("<p>Created userID " + iNewUserID + " with name of " + sNewUserName + ", password of " + sNewUserPass + ",  and group memberships of " + sGroups.Replace(","," & ") + ".");
							} 
							else 
							{
								Response.Write("<p>After creating " + sNewUserName + ", the operation failed to add the list of group memberships.");
							}
						}
					}
				}
				else if (sAction == "delete")
				{
					bool bOnlyDeleteFromPTAuth = (ConfigurationSettings.AppSettings["only-delete-from-ptauthsoure"] == "true") ? true : false;
					om = session.GetUsers(); //Query for all
					qr = om.SimpleQuery(iDestinationFolder, PT_PROPIDS.PT_PROPID_NAME); 
					Response.Write("<p>" + qr.RowCount() + " users existed in the folder ''" + sDestinationFolderName + "''.<ul><table>");
					for (int i=0 ; i<qr.RowCount() ; i++) 
					{
						int iUserID = qr.ItemAsInt(i,PT_PROPIDS.PT_PROPID_OBJECTID);
						string sName = qr.ItemAsString(i,PT_PROPIDS.PT_PROPID_NAME);
						int iAuthSourceID = qr.ItemAsInt(i,PT_PROPIDS.PT_PROPID_USER_AUTHSOURCE);
						Response.Write("<tr><td>" + DeleteUser(iUserID, sName, iAuthSourceID, sAdminName, bOnlyDeleteFromPTAuth, session) + "</td></tr>");
					}
					Response.Write("</table></ul>");
				}
				else if (sAction == "show")
				{
					om = session.GetUsers(); //Query for all
					qr = om.SimpleQuery(iDestinationFolder, PT_PROPIDS.PT_PROPID_NAME); 
					Response.Write("<p>" + qr.RowCount() + " users exist in the folder ''" + sDestinationFolderName + "''. Existing users are shown.<ul><table>");
					for (int i=0 ; i<qr.RowCount() ; i++) 
					{
						string sName = qr.ItemAsString(i,PT_PROPIDS.PT_PROPID_NAME);
						Response.Write("<tr><td>" + sName + "</td></tr>");
					}
					Response.Write("</table></ul>");
				}
				else
				{
					Response.Write("<p>Sorry. You need to tell me through the query string what to do. For help, see the <a href=readme.html>readme</a>.");
				}
			}
		}

		private string DeleteUser(int iUserID, string sName, int iAuthSourceID, string sAdminName, bool bOnlyDeleteFromPTAuth, IPTSession session) 
		{
			if (sName.ToLower()==sAdminName.ToLower()) 
			{
				return "Will not deleted user " + iUserID.ToString() + " named " + sName + " because this is the name of the user who runs this web application.";
			} 
			else if (!bOnlyDeleteFromPTAuth || iAuthSourceID ==1)
			{
				session.GetUsers().Delete(iUserID);
				return "Deleted user " + iUserID.ToString() + " named " + sName;
			}
			else 
			{
				return "Will not delete user " + iUserID.ToString() + " named " + sName + " because it is not a member of the PT Auth Source.";
			}
		}

		private static int CreateUser( string sName, string sPass, int iFolder, IPTSession session ) 
		{
			// create a new user and add those values
			IPTUser user=(IPTUser)session.GetUsers().Create(iFolder);
			user.SetName(sName);
			user.SetPassword(sPass);
			
			//Get the IPTServerContextinterface from the user
			IPTServerContext sc=(IPTServerContext)user.GetInterfaces("IPTServerContext");
			
			//Store it and unlock
			sc.Store();
			sc.UnlockObject();
			// PTDebug.Trace(com.plumtree.debug.Component.WebServicesSessionAPI, TraceType.Info, "Creating new user " + sName + " in folder " + iFolder);
			
			//Get the ID
			return sc.GetObjectID();
		}

		private static bool ChangeUserName ( int iUserID, string sLoginName, IPTSession session) 
		{
			// PTDebug.Trace(com.plumtree.debug.Component.WebServicesSessionAPI, TraceType.Info, "Attempting to change username and loginname for  " + iUserID + ".");
			try 
			{
				IPTUser user = (IPTUser)session.GetUsers().Open(iUserID,true);
				user.SetLoginName(sLoginName);
				user.SetName(sLoginName);
				IPTServerContext sc = (IPTServerContext)user.GetInterfaces("IPTServerContext");
				sc.Store();
				sc.UnlockObject();
				// PTDebug.Trace(com.plumtree.debug.Component.WebServicesSessionAPI, TraceType.Debug, "Successfully changed username and loginname for  " + iUserID + " to " + sLoginName + ".");
				return true;
			} 
			catch 
			{
				// PTDebug.Trace(com.plumtree.debug.Component.WebServicesSessionAPI, TraceType.Error, "Failed to change username and loginname for  " + iUserID + " to " + sLoginName + ".");
				return false;
			}
		}
		
		private static bool AddUserToGroups( int iUserID, string[] strArrGroups, IPTSession session ) 
		{
			// loop through groups and add user to each
			try 
			{
				// PTDebug.Trace(com.plumtree.debug.Component.PlumtreeDLL, TraceType.Info, "Begin adding user " + iUserID + " to groups:");
				int i, groupInt;
				for (i = 0; i<strArrGroups.Length; i++) 
				{
					// get an int value from the string value for the group, then open group and add user
					groupInt = Convert.ToInt32(strArrGroups[i]);
					// PTDebug.Trace(com.plumtree.debug.Component.WebServicesSessionAPI, TraceType.Debug, "---Adding user " + iUserID + " to group " + groupInt);
					IPTUserGroup group = (IPTUserGroup)session.GetUserGroups().Open(groupInt,false);
					group.AddUsers(iUserID);
				}
				return true;
			} 
			catch 
			{
				// PTDebug.Trace(com.plumtree.debug.Component.WebServicesSessionAPI, TraceType.Error, "Failed to add user " + iUserID + " to all groups beginning with " + strArrGroups[0] + ".");
				return false;
			}
		}

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
		}
		#endregion
	}
}
