// wmwsrouter2Obj.h : Declaration of the Cwmwsrouter2Obj
//
// Copyright (c) 2002 Robert Cunnings. All rights reserved.
//
// You may copy, modify, distribute or publish this code free of charge.
//
// NO WARRANTY: This software is provided AS IS, without warranty of any kind.
//
//////////////////////////////////////////////////////////////////////
//
// Cwmwsrouter2Obj class - implementation of Web Services Routing Protocol.
// 
//////////////////////////////////////////////////////////////////////

#pragma once
#include "resource.h"       // main symbols

#include "wmwsrouter.h"

#include "comdef.h"
#include "..\wmsoapmsg\wmsoapmsg.h"
#include <string>
#include <list>
using namespace std;

class WMXMLElement;

// Cwmwsrouter2Obj

class ATL_NO_VTABLE Cwmwsrouter2Obj : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<Cwmwsrouter2Obj, &CLSID_wmwsrouter2>,
	public IDispatchImpl<Iwmwsrouter2, &IID_Iwmwsrouter2, &LIBID_wmwsrouterLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
	Cwmwsrouter2Obj()
	{
	}

DECLARE_REGISTRY_RESOURCEID(IDR_WMWSROUTER2OBJ)


BEGIN_COM_MAP(Cwmwsrouter2Obj)
	COM_INTERFACE_ENTRY(Iwmwsrouter2)
	COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()


	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}
	
	void FinalRelease() 
	{
	}

public:
	STDMETHOD(OnProcessHeader)(/*[in]*/ VARIANT SOAPMsgInterface, /*[out, retval]*/ VARIANT_BOOL *pResult);
	STDMETHOD(OnTestMUHeaderBlock)(/*[in]*/ BSTR bstrNamespace, /*[in]*/ BSTR bstrLocalName, /*[out, retval]*/ VARIANT_BOOL *pResult);

private:
	bool ReadHeader(Iwmsoapmsg2 *pIwmsoapmsg);
	bool ProcessRequest(Iwmsoapmsg2 *pIwmsoapmsg);
	bool ProcessResponse(Iwmsoapmsg2 *pIwmsoapmsg);
	bool ReadViaList(WMXMLElement *pListElem, list<wstring>& listViaList);
	bool ReadFoundList(WMXMLElement *pListElem, list<wstring>& listFoundList);
	bool CheckIdentity(const wstring& wstrURL, Iwmsoapmsg2 *pIwmsoapmsg);
	bool CheckURLScheme(const wstring& wstrURL);
	bool ProcessFault(int nCode, Iwmsoapmsg2 *pIwmsoapmsg);
	bool ProcessReqAsIntermediary(Iwmsoapmsg2 *pIwmsoapmsg);
	bool ProcessReqAsEndpoint(Iwmsoapmsg2 *pIwmsoapmsg);
	bool ProcessRespAsIntermediary(Iwmsoapmsg2 *pIwmsoapmsg);
	bool ProcessRespAsEndpoint(Iwmsoapmsg2 *pIwmsoapmsg);
	bool PopulateViaList(list<wstring>& listViaList, WMXMLElement *pListElem);
	bool PopulateAtList(list<wstring>& listAtList, WMXMLElement *pListElem);
	bool ReadFault(WMXMLElement *pFaultElement);
	bool ForwardMsgHTTP(const wstring& wstrURL, Iwmsoapmsg2 *pIwmsoapmsg);
	WMXMLElement *CreateFaultElem();
	WMXMLElement *CreateSOAPFault(int nCode, Iwmsoapmsg2 *pIwmsoapmsg);
	wstring GenerateId();
	wstring GetFromURI();

	// "path" struct members
	wstring			m_wstrAction;
	wstring			m_wstrTo;
	list<wstring>	m_listFwd;
	list<wstring>	m_listRev;
	wstring			m_wstrFrom;
	wstring			m_wstrId;
	wstring			m_wstrRelatesTo;

	// "fault" struct members
	wstring			m_wstrFaultcode;
	wstring			m_wstrFaultreason;
	wstring			m_wstrEndpoint;
	list<wstring>	m_listFound;
	wstring			m_wstrMaxsize;
	wstring			m_wstrMaxtime;
	wstring			m_wstrRetryAfter;

	// additional fault information
	bool		m_bNeedEndpoint;
	bool		m_bNeedFound;
	bool		m_bNeedMaxsize;
	bool		m_bNeedMaxtime;
	bool		m_bNeedRetryAfter;

	// existence flags
	bool		m_bActionElemFound;
	bool		m_bToElemFound;
	bool		m_bFwdElemFound;
	bool		m_bRevElemFound;
	bool		m_bFromElemFound;
	bool		m_bIdElemFound;
	bool		m_bRelatesToElemFound;
	bool		m_bFaultElemFound;

	wstring		m_wstrURI;
	wstring		m_wstrIntermediaryURI;
	bool		m_bRequestFault;
	bool		m_bIntermediary;
	bool		m_bNoReversePath;
	bool		m_bAbortProcessing;
};

OBJECT_ENTRY_AUTO(__uuidof(wmwsrouter2), Cwmwsrouter2Obj)
