/***************************************************************************
                Proper storage info collect thread class
                -----------------------------------------
    begin      : 2014/02/27
    copyright  : (C) 2005 SolutionBox Inc.
    author     : solbox dev team
    email      : huibong@solbox.com
    version    : 3.3.0

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

#ifndef __PROPER_STORAGE_H__
#define __PROPER_STORAGE_H__


#include <pthread.h>
#include <string>
#include <vector>
#include <unistd.h>


// 시스템에서 추출된 Mount 정보를 저장하기 위한 struct...
struct systme_mount_info {

	std::string mount_name;                  // Mount Name..

	unsigned long long available_byte;       // available byte
};


/// @brief CProperStorage
/// 본 클래스는 Thread 클래스로서 
/// 장비에 mount 된 경로 정보 중... 가장 Free 용량이 많은 Mount 경로 정보를 반환한다.
/// 각 Mount 에 대한 검사는 주기적으로 Thred 에 의해 동작된다.
class CProperStorage
{
	public:
		/// @brief 생성자
		/// @param [in] strStorageRoot 전체 Mount 된 경로 정보 중 사용할 최상위 경로 정보. ( /stg , /user2/dav_storage  등 )
		/// @param [in] nCheckInterval 각 Mount 정보에 대한 상태 검사 주기, 초(sec) 단위
		CProperStorage( const std::string & strStorageRoot, const int nCheckInterval );

		~CProperStorage();


		/// @brief Thread 기동 함수
		/// @param none
		/// @return 성공시 true, 그 외 false
		bool Start();


		/// @brief 생성자에 전달된 최상위 경로 정보를 바탕으로 시스템에 Mount 된 정보를 검사하여...
		///        Content Write 에 가장 적절한 mount 경로정보를 전달한다.
		/// @param [out] strProperPath Content Write 에 가장 적절한 Mount 경로 ( /stg/node0, /stg/node1, /user2/dav_storage 등 )
		/// @return 성공시 true, 그 외 false
		bool GetProperPath( std::string& strProperPath );
		bool GetProperPath( std::string& strProperPath, unsigned long long & nAvailableSzie );

		/// Content Write 에 가장 적절한 mount 경로정보의 Free Size 정보. ( Byte 단위)
		//  - GetProperPath() 함수를 통해 경로 정보 수신 후 본 함수를 호출할 경우...
		//  - Thread 에 의해 경로 정보 및 Free 용량 정보가 변경되어 다른 경로에 대한 Free 용량 정보가 전달될 수 있으니... 사용시 주의한다.
		void GetAvailableSize( unsigned long long & nAvailableSzie );


    private:

		// 생성자를 통해 전달받은 최상위 경로 정보 저장. 
        std::string m_strStorageRoot;
		// Mount 정보에 대한 검사 주기 (생성자를 통해 전달받음, sec 단위 )
        int m_nCheckInterval;


		// Thread 에서 검사된 최적의 Content Write 경로 정보 저장 변수. ( 주기적으로 변경됨 )
		std::string m_strProperPath;
		// 추출된 m_strProperPath 경로의 Free Size ( Byte 단위 )
		unsigned long long m_nAvailableSize;
	

		// 검사 결과 저장 관련 m_strProperPath, m_nAvailableSize 에 대해 동시 get, set 처리 관련 Mutext lock
		pthread_mutex_t m_mutexLock;

		// systme 에서 추출된 mount 상태 정보를 저장하기 위한 vector 변수
		std::vector<struct systme_mount_info> m_vecMount;


	private:

		// 쓰레드 핸들
        pthread_t m_threadHandle;

		// 쓰레드 함수..
        static void * threadFunc( void * arg );

		// 실제 경로 최적 Mount 경로 정보 추출을 담당할 함수.
		void Execute( void );

		// FHS 장비의 Mount 정보를 추출하여... 멤버 변수인 m_vecMount 에 저장한다.
		// return true  : Mount 정보 정상 추출시...
		//        false : Mount 정보 추출 실패 또는 추출된 Mount 정보가 없는 경우...
		bool GetSystmeMountInfo();


		// 전달받은 경로로부터.. 상위 Path 정보를 추출하여 전달한다.
		// 오류 발생시 [out] 값인 strUpperPath 가 empty 된다.
		void GetUpperPath( const std::string & strSourcePath, std::string & strUpperPath );

		// Content Write 관련 최적 Mount 경로 및 사용 가능 Free Size 를 설정한다.
		void SetProperPath( std::string& strProperPath, unsigned long long & nAvailableSzie );

		// Content Write 관련 최적 Mount 경로 및 사용 가능 Free Size 추출 실패시..
		void SetProperPathError();

		// 인자로 전달받은 Mount 에 대해 disable flag 가 등록되어 있는지 검사
		bool CheckMountDisable( const std::string & strMountName);


		// vector 정렬 함수.
		//bool SortMountAvailableSize( struct systme_mount_info & fisrt, struct systme_mount_info & second);


};

#endif //__PROPER_STORAGE_H__
