/****************************************************************************
                Service status check & shared memory set class
                -----------------------------------------

    begin      : 2015/05/06
    copyright  : (C) 2005 Solbox Inc.
    author     : Dev Storage Team
    email      : huibong@solbox.com
    version    : 3.5

    CopyRight(C) 2005 Solbox Inc. All Rights reserved.
    Redistribution and use in source and binary forms, with or with out
    modification, are not permitted in outside of Solbox Inc.
*****************************************************************************/

#ifndef __SERVICE_CHECK_H__
#define __SERVICE_CHECK_H__

#include "FhsShm.h"
#include "StorageInfo.h"

#include <string>
#include <vector>


// NIC 에 할당된 IP Type (AF_INET or AF_INET6) , IP 주소 정보를 저장하기 위한 구조체.
struct IpAddressInfo {

	int type;            // AF_INET or AF_INET6
	std::string ip;      // ip address
};


// ZFS 상태 정보  열거형 변수
typedef enum TypeZfsStatus {
	ZFS_ERROR = -1,		// Storage 상태 정보 수집 실패, FAULTED, OFFLINE, UNAVAIL 상태인 경우 -> Service Disable 처리 필요
	ZFS_ONLINE,			// 정상 상태 또는 ZFS 아닌 경우
	ZFS_READONLY		// DEGRADED 상태 -> Read only 처리 필요

} ZfsStatus;


// Service 상태 정보를 Check 하고... 그 결과를 공유메모리에 저장처리 하기 위한 class
class CServiceCheck
{
	public:

		// 생성자
		CServiceCheck( CFhsShm * pFhsShm );

		// 소멸자
		~CServiceCheck();

		// 초기화 함수
		// - 초기화 작업 실패시 false 반환함.
		bool Init( std::vector<std::string> vecNic, std::vector<std::string> vecDns, unsigned int uFimngdPort );

		// Service 상태 Check 시작..
		// - 오류 발생시.. false 반환.
		bool Check();
		

	private:  // Service Check 관련 멤버 변수

		// 공유메모리 interface 객체에 대한 포인터.
		// -  공유메모리에 Data Set, Get 을 담당
		CFhsShm * m_pFhsShm;
		

		// Service NIC name 정보 저장.
		std::vector<std::string> m_vecServiceNic;	

		// DNS resolve check 대상 dns name
		// - 설정값이 존재하지 않을 수 있음
		std::vector<std::string> m_vecCheckDns;

		// fimngd check 관련 port 번호
		unsigned int m_uCheckFimngdPort;

		// fimngd 접속 실패 관련 count 정보를 저장하기 위한 변수.
		// - 최초 기동시 -1 로 설정 처리.
		int m_iFimngdDeadCount;
						

		// Service NIC 에 할당된 IP 정보를 저장하기 위한 변수.
		std::vector<struct IpAddressInfo> m_vecServiceIp;


		// Storage 의 ZFS 여부 정보를 추출, 판단 처리할 Stroage Info 객체
		CStorageInfo m_storageInfo;


		struct timespec m_timeStart;	// service check 소요시간 측정을 위한 멤버변수
		struct timespec m_timeEnd;		// service check 소요시간 측정을 위한 멤버변수
		double m_dElapsedTime;			// service check 소요시간 측정을 위한 멤버변수


	private:  // Check 관련 내부 함수

		// fsck 프로세스 동작 여부 체크.
		// - true  : 해당 프로세스 동작 중
		// - false : 동작 안함.
		bool IsFsckRun();

		// 멤버 변수 m_vecSvcNic 에 저장된 서비스 NIC 에 대한 상태 체크 수행
		// - true  : 모두 정상
		// - false : 오류 발생 또는 1개라도 active 상태가 아닌 경우.
		bool IsAliveServiceNic();

		// 멤버 변수 m_vecSvcNic 에 저장된 서비스 NIC 에 대한 IP 정보를 추출하여 멤버 변수 m_vecServiceIp 에 저장
		// - true  : 추출 성공시.
		// - false : 추출된 service IP 정보가 존재하지 않는 경우. ( 오류 발생 등으로 인해 추출 불가시 포함)
		bool GetServiceIp();

		// Apache 의 80 port 에 접속 가능한지 check.
		// return  true  : 정상
		//         false : 추출된 서비스 IP 로 접속 테스트 수행시.. 1개라도 접속이 실패한 경우(Timeout 발생 포함)
		// - 2015-05-11 현재 opendav 가 80 port listen 처리시 IPv4 에 대해서만 Listen 처리하므로...
		// - 추출된 서비스 IP 중 IPv4 에 대해서만 테스트를 수행한다.
		bool IsAliveApache();
		
		// DNS resolve 체크 수행.
		// - 장비의 hostname 을 기준으로 m_vecCheckDns 에 정의된 DNS 서버에 resolve 질의
		// - resolve 결과가.. m_vecServiceIp 에 존재하는 경우.. true.
		// - 만약 resolve 결과가 m_vecServiceIp 에 존재하지 않는 경우... 
		// -- 해당 domain 이 다른 장비를 가르키는 것일 수 있으므로.. fasle 반환.
		bool IsResolveDns();

		// Default DNS resolve check
		// - 장비의 hostname 을 기준으로 시스템에 설정된 기본 DNS 서버에 resolve 질의
		// - resolve 결과가.. m_vecServiceIp 에 존재하는 경우.. true.
		// - 위의 DNS check 관련 설정 정보가 없거나.. Alive DNS 가 없는 경우 처리를 수행하기 위한 보조 방법임
		bool IsResolveDefaultDns();


		// std 상에 trim 함수가 없어서 직접 구현. 아니면 boost/algorithm/string.hpp 상의 boost::trim 함수 사용
		// @return void
		void Trim( std::string & str );

		// FHS 의 fimngd 프로세스 동작 여부 check.
		// - init() 에서 설정된 m_uCheckFimngdPort 정보와 추출된 서비스 IP 를 이용하여 TCP 접속 테스트 수행.
		// @return true  접속 성공시
		//         false 접속 실패 또는 오류 발생시.
		bool IsAliveFimngd();

		// Storage Write/Read 테스트 결과가 정상인지 Check
		// - Storage 저장 공간에 대한 file write / read 테스트가 worker 프로세스에 의해 주기적으로 수행
		// - 만약 test 실패 발생시 공유 메모리 상의 관련 값이 -1 로 설정됨
		// - 만약 test 중 hang 발생시 공유 메모리 상의 값을 확인하여 timeout 여부 판단 필요.
		// @return true  storage check 정상인 경우
		//         false storage check 실패 또는 timeout 상황인 경우
		bool IsNormalStatusStorageCheck();

		// System Collecotr 관련 Worker 프로세스가 정상 동작하는지 Check
		// - system 상태 정보 수집을 위한 system collector worker 프로세스는 주기적으로 수행되며
		// - 수집 시작시간, 수집된 정보를 공유메모리에 저장 
		// - 만약 여러 요인에 의해 해당 worker 프로세스가 hang 상황인 경우 서비스 상태를 disable 로 변경 처리해야 함
		// - 이를 판단하기 위한 함수로 공유메모리 정보를 이용하여 timeout 판단함.
		// @return true  정상인 경우
		//         false timeout 상황인 경우
		bool IsNormalStatusSystemCollect();

		// ZFS 상태 관련 정보 추출하여 정상인지 Check
		ZfsStatus GetZfsStatus();



};


#endif /* __SERVICE_CHECK_H__ */
