using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.Data.SqlClient;
using System.Web.Security;
using System.Configuration;
using Microsoft.ApplicationBlocks.Data;

namespace BookCommunityService
{
	[WebService(Namespace="http://www.BookCommunity.org")]
	public class AuthService : System.Web.Services.WebService
	{
		public AuthService()
		{
			//CODEGEN: 该调用是 ASP.NET Web 服务设计器所必需的
			InitializeComponent();
		}

		internal System.Data.SqlClient.SqlConnection dbConn;

		#region 组件设计器生成的代码
		
		//Web 服务设计器所必需的
		private IContainer components = null;
				
		/// <summary>
		/// 设计器支持所需的方法 - 不要使用代码编辑器修改
		/// 此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			System.Configuration.AppSettingsReader configurationAppSettings = new System.Configuration.AppSettingsReader();
			this.dbConn = new System.Data.SqlClient.SqlConnection();
			// 
			// dbConn
			// 
			this.dbConn.ConnectionString = ((string)(configurationAppSettings.GetValue("dbConn.ConnectionString", typeof(string))));

		}

		/// <summary>
		/// 清理所有正在使用的资源。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if(disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);		
		}
		
		#endregion

		// WEB 服务示例
		// HelloWorld() 示例服务返回字符串 Hello World
		// 若要生成，请取消注释下列行，然后保存并生成项目
		// 若要测试此 Web 服务，请按 F5 键

//		[WebMethod]
//		public string HelloWorld()
//		{
//			return "Hello World";
//		}
		
		[WebMethod()]
		public string GetAuthorizationTicket(string userName, string password)
		{
			// try to authenticate the user
			string userID=null;

			try
			{
				//				if(dbConn.State != ConnectionState.Open)
				//					dbConn.Open();
				//object obj = SqlHelper.ExecuteScalar(dbConn, "AuthenticateUser", userName, password);
				userID = SqlHelper.ExecuteScalar(dbConn, "AuthenticateUser", userName, password).ToString();
				//				SqlCommand cmd = new SqlCommand();
				//				cmd.CommandText = "[AuthenticateUser]";
				//				cmd.CommandType = CommandType.StoredProcedure;
				//				cmd.Connection = dbConn;
				//
				//				cmd.Parameters.Add("@Username",SqlDbType.NVarChar,50,"UserName");
				//				cmd.Parameters.Add("@Password",SqlDbType.NVarChar,50,"Password");
				//
				//				cmd.Parameters["@Username"].Value = userName;
				//				cmd.Parameters["@Password"].Value = password;
				//
				//				userID = cmd.ExecuteScalar();

			}
			catch(Exception ex)
			{
				string str = ex.Message;
			}
			finally
			{
				dbConn.Close();
			}
			
			if (userID == null)
			{
				// The user name and password combination is not valid.
				return null;
			}

			try
			{
				// create the ticket
				FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(userID, false, 1);
				string encryptedTicket = FormsAuthentication.Encrypt(ticket);

				// get the ticket timeout in minutes
				AppSettingsReader configurationAppSettings = new AppSettingsReader();
				int timeout = (int) configurationAppSettings.GetValue("AuthenticationTicket.Timeout", typeof(int));

				// cache the ticket
				Context.Cache.Insert(encryptedTicket, userID, null, DateTime.Now.AddMinutes(timeout), TimeSpan.Zero);

				return encryptedTicket;
			}
			catch(Exception ex)
			{
				string str = ex.Message;
				return null;
			}
		}


		[WebMethod()]
		public UserInformation GetUserInfo(string ticket)
		{
			if (!IsTicketValid(ticket, false))
				return null;

			int userID = int.Parse(FormsAuthentication.Decrypt(ticket).Name);

			DataSet ds;
            
			try
			{
				ds = SqlHelper.ExecuteDataset(dbConn, "GetUserInfo", userID);
			}
			finally
			{
				dbConn.Close();
			}

			
			UserInformation userInfo = new UserInformation();
            
			DataRow dr = ds.Tables[0].Rows[0];

			userInfo.Address		= dr["Address"] as string;
			userInfo.Company		= dr["Company"] as string;
			userInfo.CompanyAddress	= dr["CompanyAddress"] as string;
			userInfo.Credit			= (int)dr["Credit"];
			userInfo.Email			= dr["Email"] as string;
			userInfo.HomePhone		= dr["HomePhone"] as string;
			userInfo.ID				= (int)dr["ID"];
			userInfo.MobilePhone	= dr["MobilePhone"] as string;
			userInfo.Password		= dr["Password"] as string;
			userInfo.RealName		= dr["RealName"] as string;
			userInfo.UserName		= dr["UserName"] as string;
			userInfo.WorkPhone		= dr["WorkPhone"] as string;

			return userInfo;
		}

		[WebMethod()]
		public int InsertUser(UserInformation userInfo)
		{
//			if (!IsTicketValid(ticket, true))
//				return -1;

			try
			{
				object userID = null;
				userID = SqlHelper.ExecuteScalar(dbConn, "UserInfoInsertCommand", userInfo.RealName, 
					userInfo.UserName, userInfo.Password,
					userInfo.Address, userInfo.Email,
					userInfo.MobilePhone, userInfo.HomePhone,
					userInfo.WorkPhone, userInfo.Company,
					userInfo.CompanyAddress,userInfo.Credit);

				if (userID == null)
				{
					return -1;
				}
				else
				{
					// Note: @@identity return type is decimal--need to Convert to int!
					return Convert.ToInt32(userID.ToString());
				}
			}
			catch (SqlException ex)
			{
				if (ex.Number == 2627)
				{
					// SQL Server has detected a unique key constraint violation on
					// the UserName column.  Return the flag value for this case.
					return 0;
				}
				else
				{
					throw ex;
				}
			}
			finally
			{
				dbConn.Close();
			}
		}



		[WebMethod()]
		public UserInformation ChangePassword(string ticket, UserInformation userInfo)
		{
			if (!IsTicketValid(ticket, false))
				return null;

			int userID = int.Parse(FormsAuthentication.Decrypt(ticket).Name);

			int result=0;

			try
			{
//				result = SqlHelper.ExecuteNonQuery(dbConn, "ChangePassword", userInfo.UserPassword, userID);
			}
			finally
			{
				dbConn.Close();
			}
			
			if (result == 1)
				return userInfo;
			else
				return null;
		}

		private bool IsTicketValid(string ticket, bool IsAdminCall)
		{
			if (ticket == null || Context.Cache[ticket] == null)
			{
				// not authenticated
				return false;
			}
			else
			{
				// check the user authorization
				int userID = int.Parse(FormsAuthentication.Decrypt(ticket).Name);

				DataSet ds;
				
				try
				{
					ds = SqlHelper.ExecuteDataset(dbConn, "GetUserInfo", userID);
				}
				finally
				{
					dbConn.Close();
				}

				UserInformation userInfo = new UserInformation();

				DataRow dr = ds.Tables[0].Rows[0];

//				userInfo.IsAdministrator = (bool) dr["IsAdministrator"];
//				userInfo.IsAccountLocked = (bool) dr["IsAccountLocked"];

//				if (userInfo.IsAccountLocked)
//					return false;
//				else
				{
					// check admin status (for admin required calls)
//					if (IsAdminCall && !userInfo.IsAdministrator)
//						return false;
									   
					return true;
				}
			}					   
		}
	}
}
