//=================================================================
//
//        TestResource.h
//
//        Test resource class
//
//=================================================================
//####COPYRIGHTBEGIN####
//
// -------------------------------------------
// The contents of this file are subject to the Cygnus eCos Public License
// Version 1.0 (the "License"); you may not use this file except in
// compliance with the License.  You may obtain a copy of the License at
// http://sourceware.cygnus.com/ecos
// 
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
// License for the specific language governing rights and limitations under
// the License.
// 
// The Original Code is eCos - Embedded Cygnus Operating System, released
// September 30, 1998.
// 
// The Initial Developer of the Original Code is Cygnus.  Portions created
// by Cygnus are Copyright (C) 1998, 1999 Cygnus Solutions.
// All Rights Reserved.
// -------------------------------------------
//
//####COPYRIGHTEND####
//=================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):     sdf
// Contributors:  sdf
// Date:          1999-04-01
// Description:   This class abstracts test resources for use in the testing infrastructure
// Usage:
//
//####DESCRIPTIONEND####

#ifndef _TESTRESOURCE_H
#define _TESTRESOURCE_H
#include "stdafx.h"
#include "eCosTest.h"
#include "Port.h"

// This class is used to manipulate test resources.  A test resource is the means to execute
// a test (a test agent running on a tcp/ip port)
class CTestResource {
public:
    // ctors/dtors
    /*
    // Necessary if we allocate arrays of them
    CTestResource ();
    CTestResource(const CTestResource &o);
    */
    CTestResource (const char *pszImage);

    static bool ResourcesLocked();
	static void UnlockResources(const char *pszFile,int nLine);
	static void LockResources (const char *pszFile,int nLine);
    void Image (CeCosTestUtils::String &str);
	static bool SaveSocket (const char *pszHost,int nTcpPort);
	static bool LoadSocket (const char *pszHost,int nTcpPort);
	// Ctors and dtors
	CTestResource(
		const char *pszName,
		CeCosTest::TargetType Target,
		const char *pszHost,
		int nPort);

    CTestResource(
		const char *pszName,
		CeCosTest::TargetType Target,
		const char *pszHost,
		int nPort,
		const char * pszDownloadPort, int nBaud, const char *pszResetHost, unsigned int nResetPort,
			 char cControl1, char cControl2
        );
	virtual ~CTestResource();

	CeCosTest::ServerStatus Query() const;
    bool Unlock();
	bool Lock ();
	static CTestResource *First() { return pFirstInstance; }
	CTestResource *Next() const { return m_pNextInstance; }
	static void Output(FILE *f=stdout);
	static CTestResource * Lookup(const char * pszHost, int nPort, bool bSim);
    static unsigned int ResourceCount() { return nCount; }
	static void DeleteAllInstances();
	static bool LoadFile (const char *pszFileName);
	static bool SaveFile (const char *pszFileName);
	bool IsLocked() const { return m_bLocked; }
	#ifdef _WIN32
	static bool LoadReg  (); // Load information from the registry
	static bool SaveReg  (); // Save information to the registry
	#endif

	// Attributes
	const char *Host() const { return m_strHost; }
	int		    Port() const { return m_nPort; }
	const char *Name() const { return m_strName; }
	CeCosTest::TargetType Target() const { return m_Target; }
	bool Sim() const { return m_bSim; }
    const char *DownloadPort() const { return m_strPort; }
    //const char *DownloadPort2() const { return m_strPort2; }

    int Baud() const { return m_nBaud; }							// Baud rate
    char Control1()  const { return m_cControl1; }
    char Control2()  const { return m_cControl2; }
    const char *ResetHost() const { return m_strResetHost; }
    int ResetPort() const { return m_nResetPort; }
	
	void SetHost	(const char *pszHost) { m_strHost=pszHost; }
    void SetPort    (int nPort) { m_nPort=nPort; }
	void SetName	(const char *pszName) { m_strName=pszName; }
	void SetTarget	(CeCosTest::TargetType target) { m_Target=target; }
	void SetSim		(bool bSim) { m_bSim=bSim; }
    void SetBaud    (int nBaud) { m_nBaud=nBaud; }
    void SetDownloadPort(const char * pszDownloadPort) { m_strPort=pszDownloadPort; }
    void SetReset   (int nPort,char c1,char c2) { m_nResetPort=nPort; m_cControl1=c1; m_cControl2=c2; }

	// Scheduling functions
    // Get the array of resources capable of executing "e"
    // nCount gives the number of entries in ar on input
    // result is the number of entries required in ar (may exceed nCount, but this case does no damage)
    static unsigned int GetMatchCount (const CeCosTest::ExecutionParameters &e,bool bIgnoreLocking=false);
    static unsigned int GetMatches (const CeCosTest::ExecutionParameters &e,const CTestResource ** &ar,bool bIgnoreLocking=false); // as before, but callee allocates.  Deallocate using delete [].
    // Choose one from ar, using some scheduling algorithm
    static unsigned int Choose (const CeCosTest::ExecutionParameters &e, const CTestResource * const * const &ar, unsigned int nCount, int nExclude=-1);

protected:
    unsigned static int nCount;
	static void UnescapeWhitespace (CeCosTestUtils::String &str);
	static void EscapeWhitespace (CeCosTestUtils::String &str);
    void Chain();
	char m_cControl1;
	char m_cControl2;
	int m_nBaud;
    CeCosTestUtils::String m_strResetHost;
	int m_nResetPort;
    CeCosTestUtils::String m_strPort
        //,m_strPort2
        ;

	bool m_bLocked;
    CeCosTestUtils::String	m_strName;
	CeCosTest::TargetType	m_Target;
	CeCosTestUtils::String	m_strHost;
	int m_nPort;
	bool m_bSim;
	CTestResource *m_pNextInstance;
	CTestResource *m_pPrevInstance;
	static CTestResource *pFirstInstance;
    bool Matches  (const CeCosTest::ExecutionParameters &e,bool bIgnoreLocking=false) const;
};
#endif
