using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using EnterpriseDesktop.Contacts.DataLayer;
using EnterpriseDesktop.Contacts.DataLayer.ContactDataSetTableAdapters;
using System.Collections.Generic;
using EnterpriseDesktop.Contacts.Translator;
using EnterpriseDesktop.Contacts.BusinessLayer;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.Security;
using System.Security;

[WebService(Namespace = "http://enterprisedesktop/webservices/contacts")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
    public Service () {

        //Uncomment the following line if using designed components 
        //InitializeComponent(); 
    }

    //[WebMethod(CacheDuration=3600)] // example of caching a service
    [WebMethod]
    public ContactDataSet GetAllContacts()
    {
        ContactTableAdapter ta = new ContactTableAdapter();
        ContactDataSet ds = new ContactDataSet();
        
        ds.Merge(ta.GetData());
        return ds;
    }


    [WebMethod]
    public EnterpriseDesktop.Common.Validation.BrokenRulesList ValidateContact(ContactDataSet contact)
    {
        contact.EnforceConstraints = false;
        if (contact.Contact.Rows.Count > 0)
        {
            ContactDataSet.ContactRow row = contact.Contact.Rows[0] as ContactDataSet.ContactRow;
            TranslateBetweenContactRowAndContact translator = new TranslateBetweenContactRowAndContact(); ;
            Contact contactEntity =  translator.TranslateContactRowToContact(row);
            contactEntity.AddValidationRules();
            contactEntity.Validate();
            if (contactEntity.BrokenRules.Count > 0)
            {
                return contactEntity.BrokenRules;
            }
            else
            {
                return null;
            }
        }
        else
        {
            throw new NullReferenceException();
        }
    }

    [WebMethod]
    public bool SaveContact(ContactDataSet contact, out EnterpriseDesktop.Common.Validation.BrokenRulesList brokenRules)
    {
        contact.EnforceConstraints = false;
        brokenRules = null;

        // Get the row coming into service
        ContactDataSet.ContactRow row = contact.Contact.Rows[0] as ContactDataSet.ContactRow;
        // Translate it into a business entity
        TranslateBetweenContactRowAndContact translator = new TranslateBetweenContactRowAndContact();
        Contact contactBusEntity = translator.TranslateContactRowToContact(row);
        // add our rules
        contactBusEntity.AddValidationRules();

        // validate it
        contactBusEntity.Validate();
        
        if (contactBusEntity.BrokenRules.Count > 0)
        {
            brokenRules = contactBusEntity.BrokenRules;
            return false;
        }

        // so the contact saves, we add the values that cannot be null
        // the rules surrounding these would be added into the contact entity as well
        // yes, i'm cheating for demo purposes :)
        row.NameStyle = false;
        row.EmailPromotion = 1;
        row.PasswordHash = "hash";
        row.PasswordSalt = "salt";
        row.rowguid = Guid.NewGuid();
        row.ModifiedDate = DateTime.Now;

        // now save the record
        ContactTableAdapter ta = new ContactTableAdapter();
        ta.Update(contact);
        return true;
    }

    /// <summary>
    /// This method is used to demonstrate three different EntLib blocks in one method.
    /// It shows how you would handle Enterprise Library for 
    /// data access and exception handling as well as security.  
    /// </summary>
    /// <param name="table"></param>
    /// <returns></returns>
    [WebMethod]
    public System.Data.DataSet GetTableData(string table)
    {
        try
        {
            IAuthorizationProvider provider = AuthorizationFactory.GetAuthorizationProvider();
            if (provider.Authorize(User, "GetTableData"))
            {
                Database db = DatabaseFactory.CreateDatabase("EnterpriseDesktop.Contacts.DataLayer.Properties.Settings.AdventureWorksConnectionString");
                DbCommand cmd = db.GetSqlStringCommand("SELECT * FROM " + table);
                System.Data.DataSet ds = db.ExecuteDataSet(cmd);
                // don't need to close the connection, ExecuteDataSet already does this
                return ds;
            }
            else
            {
                throw new System.Security.SecurityException("You are not authorized to execute this method.  Please contact the helpdesk.");
            }
        }
        catch (System.Data.SqlClient.SqlException ex)
        {
            ExceptionPolicy.HandleException(ex, "DatabaseException");
            throw ex;
        }
        catch (SecurityException ex)
        {
            ExceptionPolicy.HandleException(ex, "Exception");
            throw;
        }
    }
}
