//------------------------------------------------------------------------------
// <copyright file="HelloWorldService.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// <summary>
//      Sample SOA service demonstrating how to interact with ExcelDriver
//      on a cluster.
// </summary>
//------------------------------------------------------------------------------

namespace HelloWorldService
{
    using System;
    using System.ServiceModel;
    using Microsoft.Hpc.Excel;
    using Microsoft.Hpc.Scheduler.Session;
    using Microsoft.Office.Interop.Excel;

    /// <summary>
    /// Class implementing Service behavior defined in IHelloWorldService
    /// </summary>
    [ServiceBehavior(IncludeExceptionDetailInFaults = true,
        InstanceContextMode = InstanceContextMode.Single,
        ConcurrencyMode = ConcurrencyMode.Single)]
    public class HelloWorldService : IHelloWorldService
    {
        #region PrivateMemberVariables

        /// <summary>
        /// Excel Driver abstracting excel application and workbook interaction
        /// </summary>
        private ExcelDriver xl;

        /// <summary>
        /// Flag to remember if a workbook has already been loaded by ExcelDriver
        /// </summary>
        private bool workbookLoaded = false;

        #endregion

        /// <summary>
        /// Initializes a new instance of the HelloWorldService class.
        /// </summary>
        static HelloWorldService()
        {
            // Register exiting event
            SetOnExitingHook();
        }

        /// <summary>
        /// Operation contract implementation that runs the SayHi macro and reads the 
        /// resulting message from cell A1.
        /// </summary>
        /// <param name="workbookPath">Path to workbook containing SayHi macro</param>
        /// <param name="recipientName">Name to say hi to</param>
        /// <param name="recipientNumber">Request number - for demonstration purposes</param>
        /// <returns>Message in the form - *number*: Hello *name*!</returns>
        public string SayHi(string workbookPath, string recipientName, int recipientNumber)
        {           
            // Check if workbook already loaded
            if (this.workbookLoaded == false)
            {
                // Create new instance of excel driver and open the specified workbook
                this.xl = new ExcelDriver();
                this.xl.OpenWorkbook(workbookPath);
                this.workbookLoaded = true;
            }

            // Run the SayHi macro, providing name to say hi to, request identifier, and compute node name               
            this.xl.RunMacro("SayHi", recipientName, recipientNumber, Environment.MachineName);

            // Retrieve message from workbook
            // Note - it is often easier to just take the result from the macro rather than using cell values
            //        but this is intended to show how to use the cell value manipulation functions.
            return (string)this.xl.GetCellValue("A1");          
        } // SayHi Method

        /// <summary>
        /// Adds OnExiting event handler to dispose ExcelDriver and clean up workbook recovery data
        /// </summary>
        private static void SetOnExitingHook()
        {
            // Set OnExiting event handler
            ServiceContext.OnExiting += new EventHandler<EventArgs>(delegate
            {
                try
                {
                    // Clean up document recovery list
                    Microsoft.Win32.Registry.CurrentUser.DeleteSubKeyTree(@"software\Microsoft\office\14.0\Excel\Resiliency\DocumentRecovery");
                }
                catch
                {
                    // Document Recovery list will not always be populated
                }
            });
        } // SetOnExitingHook method
    } // Class
} // Namespace
