// SvcStatsPage.cpp : implementation file
//

#include "stdafx.h"
#include "wmsoapsvccp.h"
#include "SvcStatsPage.h"
#include "LogonDlg.h"
#include "..\soap_source\SOAPAutomationProxy.h"
#include "..\soap_source\bytearrayconv.h"
#include "..\soap_source\WMWSDLParser.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSvcStatsPage property page

IMPLEMENT_DYNCREATE(CSvcStatsPage, CPropertyPage)

CSvcStatsPage::CSvcStatsPage() : CPropertyPage(CSvcStatsPage::IDD)
{
	//{{AFX_DATA_INIT(CSvcStatsPage)
	m_strHost = _T("");
	m_uNumConnects = 0;
	m_uNumBytesSent = 0;
	m_uNumNetErrors = 0;
	m_uNumIntErrors = 0;
	m_uNumHTTPErrors = 0;
	m_uPortNbr = 80;
	//}}AFX_DATA_INIT
}

CSvcStatsPage::~CSvcStatsPage()
{
}

void CSvcStatsPage::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSvcStatsPage)
	DDX_Control(pDX, IDC_EDIT_SVR_NAME, m_editHost);
	DDX_Control(pDX, IDC_EDIT_SVR_PORT, m_editPortNbr);
	DDX_Control(pDX, IDC_BUTTON_REFRESH, m_buttonRefresh);
	DDX_Control(pDX, IDC_BUTTON_CONNECT, m_buttonConnect);
	DDX_Text(pDX, IDC_EDIT_SVR_NAME, m_strHost);
	DDX_Text(pDX, IDC_EDIT_NUMCONNECT, m_uNumConnects);
	DDX_Text(pDX, IDC_EDIT_NUMBYTES, m_uNumBytesSent);
	DDX_Text(pDX, IDC_EDIT_NUM_NETERRORS, m_uNumNetErrors);
	DDX_Text(pDX, IDC_EDIT_NUM_INTERRORS, m_uNumIntErrors);
	DDX_Text(pDX, IDC_EDIT_NUM_HTTPERRORS, m_uNumHTTPErrors);
	DDX_Text(pDX, IDC_EDIT_SVR_PORT, m_uPortNbr);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CSvcStatsPage, CPropertyPage)
	//{{AFX_MSG_MAP(CSvcStatsPage)
	ON_BN_CLICKED(IDC_BUTTON_CONNECT, OnButtonConnect)
	ON_BN_CLICKED(IDC_BUTTON_REFRESH, OnButtonRefresh)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSvcStatsPage message handlers

void CSvcStatsPage::OnButtonConnect() 
{
	UpdateData(TRUE);
	if (m_strHost.IsEmpty())
	{
		AfxMessageBox(_T("Host name required!"));
		return;
	}
	CWSSCPApp *pApp = (CWSSCPApp *)AfxGetApp();
	// update app-wide globals
	pApp->m_strHost = m_strHost;
	pApp->m_nPort = m_uPortNbr;

	// try to reach server
	if (SetupSOAPClient() == FALSE || QueryServiceStats(true) == FALSE)
	{
		if (pApp->m_strAuthStatus == "Unauthenticated.InvalidUser")
		{
			AfxMessageBox(_T("Invalid User ID!"));
		}
		else if (pApp->m_strAuthStatus == "Unauthenticated.InvalidRealm")
		{
			AfxMessageBox(_T("Invalid Security Realm!"));
		}
		else
		{
			AfxMessageBox(_T("Unexpected Authentication failure!"));
		}
	}
	else
	{
		if (QueryServiceStats() == FALSE)
		{
			if (pApp->m_strAuthStatus == "Unauthenticated.InvalidUser")
			{
				AfxMessageBox(_T("Invalid User ID!"));
			}
			else if (pApp->m_strAuthStatus == "Unauthenticated.InvalidResponse")
			{
				AfxMessageBox(_T("Invalid User ID/Password!"));
			}
			else if (pApp->m_strAuthStatus == "Unauthenticated.InvalidRealm")
			{
				AfxMessageBox(_T("Invalid Security Realm!"));
			}
			else
			{
				AfxMessageBox(_T("Unexpected Authentication failure!"));
			}
			return;
		}
        // success
		m_bConnected = TRUE;
		m_buttonConnect.EnableWindow(FALSE);
		m_buttonRefresh.EnableWindow(TRUE);
		m_editHost.EnableWindow(FALSE);
		m_editPortNbr.EnableWindow(FALSE);
        // save settings
        pApp->WriteSettings();
	}
}

BOOL CSvcStatsPage::SetupSOAPClient()
{
	CWSSCPApp *pApp = (CWSSCPApp *)AfxGetApp();
	// build WSDL doc path
    char szBuffer[256];
    GetModuleFileName(NULL, szBuffer, 256);
    szBuffer[255] = 0;
    string strWSDL_URL("file://");
    strWSDL_URL += szBuffer;
    string::size_type pos = strWSDL_URL.rfind("\\");
    strWSDL_URL = strWSDL_URL.substr(0, pos);
    strWSDL_URL += "\\WMSOAPSvrCP.wsdl";
    // create empty header processor list to pass in
    list<wstring> listHeaderProcs;
	// initialize SOAP Client
    if (pApp->m_bUseProxy == true)
    {
	    if (pApp->m_SOAPClient.Initialize(	strWSDL_URL,
										    string((LPCSTR)pApp->m_strServiceName),
										    string((LPCSTR)pApp->m_strPortName),
										    string(""), // actor
										    string(g_pszUserAgent),
										    listHeaderProcs,
										    m_nUseExplicitTyping == 0 ? false : true,
                                            pApp->m_strProxyHost,
                                            pApp->m_nProxyPort,
                                            SOAP_VERSION_1_1) == false)
	    {
		    return FALSE;
	    }
    }
    else
    {
	    if (pApp->m_SOAPClient.Initialize(	strWSDL_URL,
										    string((LPCSTR)pApp->m_strServiceName),
										    string((LPCSTR)pApp->m_strPortName),
										    string(""), // actor
										    string(g_pszUserAgent),
										    listHeaderProcs,
										    m_nUseExplicitTyping == 0 ? false : true,
                                            SOAP_VERSION_1_1) == false)
	    {
		    return FALSE;
	    }
    }
    // set the endpoint address supplied by user
    pApp->m_SOAPClient.SetSOAPAddress(string((LPCSTR)pApp->m_strHost), pApp->m_strSvcURI, pApp->m_nPort);
	return TRUE;
}

BOOL CSvcStatsPage::QueryServiceStats(bool bInitialMsg)
{
	CWaitCursor wait;

	CWSSCPApp *pApp = (CWSSCPApp *)AfxGetApp();
	// if not first msg then renew the message object
	if (bInitialMsg == false)
	{
		if (pApp->m_SOAPClient.NewMessage() == false)
		{
			return FALSE;
		}
	}
	// method
	wstring wstrMethodName = L"GetServerStats";
	// set up call
	_variant_t Args[5];
	wstring Names[5];
	_variant_t varReturn;

	Args[0].vt = VT_I4;
	Args[0].lVal = 0;
	Names[0] = L"NumConnects";

	Args[1].vt = VT_I4;
	Args[1].lVal = 0;
	Names[1] = L"NumBytesSent";

	Args[2].vt = VT_I4;
	Args[2].lVal = 0;
	Names[2] = L"NumHTTPErrors";

	Args[3].vt = VT_I4;
	Args[3].lVal = 0;
	Names[3] = L"NumNetErrors";

	Args[4].vt = VT_I4;
	Args[4].lVal = 0;
	Names[4] = L"NumIntErrors";

	int nNumArgs = 5;

	// generate SOAP request message headers
	pApp->BuildRequestHeaders(bInitialMsg);

	// message buffer strings
	string strRequestXML;
	string strResponseXML;

	// attempt method invocation
	bool bFault = false;
	if (pApp->m_SOAPClient.InvokeSOAPMethod(wstrMethodName,
											Names,
											Args,
											nNumArgs,
											varReturn) == false)
	{
		bFault = true;
	}
	if (pApp->m_bViewBuffers == true)
	{
		MessageBox(pApp->m_SOAPClient.GetXMLOut(), "Request Message", MB_OK);
		MessageBox(pApp->m_SOAPClient.GetXMLIn(), "Response Message", MB_OK);
	}
	// load response message headers
	pApp->GetResponseHeaders();
	if (pApp->m_SOAPClient.IsSOAPFault() == true)
	{
		if (bInitialMsg == true)
		{
			if (pApp->m_strAuthStatus == "Unauthenticated.NoCredentials")
			{
                CLogonDlg dlg;
                dlg.m_strRealm = pApp->m_strRealm.c_str();
                if (dlg.DoModal() == IDOK)
                {
                    pApp->m_strUID = (LPCSTR)dlg.m_strUserId;
                    pApp->m_strPassword = (LPCSTR)dlg.m_strPassword;
				    return TRUE;
                }
                return FALSE;
			}
			return FALSE;
		}
		bFault = true;
	}
	if (bFault == true ||
		pApp->m_strAuthStatus != "Authenticated" ||
		varReturn.boolVal == VARIANT_FALSE ||
		pApp->AuthServer() == false)
	{
		return FALSE;
	}
	m_uNumConnects = Args[0].lVal;
	m_uNumBytesSent = Args[1].lVal;
	m_uNumHTTPErrors = Args[2].lVal;
	m_uNumNetErrors = Args[3].lVal;
	m_uNumIntErrors = Args[4].lVal;
	UpdateData(FALSE);	
	return TRUE;
}

void CSvcStatsPage::OnButtonRefresh() 
{
	CWaitCursor wait;
	UpdateData(TRUE);
	CWSSCPApp *pApp = (CWSSCPApp *)AfxGetApp();
	if (QueryServiceStats() == FALSE && pApp->m_bStaleNonce == true)
	{
		QueryServiceStats();
	}
	UpdateData(FALSE);	
}

BOOL CSvcStatsPage::OnKillActive() 
{
	if (m_bConnected == FALSE)
	{
		AfxMessageBox(_T("Error: Not connected to any Server!"));
		return 0;
	}
	return CPropertyPage::OnKillActive();
}

BOOL CSvcStatsPage::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();
	
	// intialize connection flag
	m_bConnected = FALSE;
	CWSSCPApp *pApp = (CWSSCPApp *)AfxGetApp();
	// read server settings
    if (pApp->ReadSettings() == false)
    {
        AfxMessageBox("Failed to read configuration file.");
        return FALSE;
    }
    m_strHost = pApp->m_strHost;
    m_uPortNbr = pApp->m_nPort;

	UpdateData(FALSE);
	m_buttonRefresh.EnableWindow(FALSE);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
