#ifndef _FishIDE_Libraries_h_
#define _FishIDE_Libraries_h_

#include "AVersion.h"

class LibraryVersion : Moveable<LibraryVersion>
{
	friend class LibrariesClass;
	friend class Library;
	
	private:
	
		// library properties
		bool			_oldStyle;
		bool			_anyArchitecture;
		String			_name;
		AVersion		_version;
		String			_author;
		String			_maintainer;
		String			_sentence;
		String			_paragraph;
		String			_website;
		String			_category;
		String			_url;
		String			_archiveFileName;
		int				_size;
		String			_checksum;
		Vector<String>	_architectures;
		Vector<String>	_types;
		
		// clear info data
		void ClearInfo(void);
		
		// read properties file
		void ReadPropertiesFile(String const &path);
		
	protected:
	
	public:
	
		// constructor
		LibraryVersion();
		
		// pick constructor
		LibraryVersion(LibraryVersion &&) = default;
		
		// destructor
		~LibraryVersion();
		
		// move operator
		LibraryVersion &operator=(LibraryVersion &&lib) = default;
	

		bool			IsOldStyle(void) const				{ return _oldStyle;			}
		String const&	GetName(void) const					{ return _name;				}
		AVersion const&	GetVersion(void) const				{ return _version;			}
		String const &	GetAuthor(void) const				{ return _author;			}
		String const &	GetMaintainer(void) const			{ return _maintainer;		}
		String const &	GetSentence(void) const				{ return _sentence;			}
		String const &	GetParagraph(void) const			{ return _paragraph;		}
		String const &	GetWebsite(void) const				{ return _website;			}
		String const &	GetCategory(void) const				{ return _category;			}
		String const &	GetUrl(void) const					{ return _url;				}
		String const &	GetArchiveFileName(void) const		{ return _archiveFileName;	}
		int				GetSize(void) const					{ return _size;				}
		String const &	GetChecksum(void) const				{ return _checksum;			}
		
		Vector<String>	const &GetArchitectures(void) const	{ return _architectures; }
		Vector<String>	const &GetTypes(void) const			{ return _types; }
		
		// get the staging archive
		String GetStagingArchivePath(void) const;

		// get library local folder
		String GetLocalFolder(void) const;
};

class Library : Moveable<Library>
{
	friend class LibrariesClass;
	
	private:
	
		// available versions
		VectorMap<MaintainerVersion, LibraryVersion> _versions;
		
		// name
		String _name;
		
		// installed flag
		bool _installed;
		
		// installed version
		MaintainerVersion _installedVersion;
	
	protected:
	
	public:
	
		// constructor
		Library();
		
		// pick constructor
		Library(Library &&lib) = default;
		
		// destructor
		~Library();
		
		Library &operator=(Library &&lib) = default;
		
		// install or update a library
		bool Install(MaintainerVersion const &ver);
		
		// uninstall the library
		bool Remove(void);
		
		// check if installed and installed version
		bool IsInstalled(void) const { return _installed; }
		MaintainerVersion const &GetInstalledVersion(void) const { return _installedVersion; }
		
		// get available versions
		VectorMap<MaintainerVersion, LibraryVersion> const &GetVersions(void) const { return _versions; }
		VectorMap<MaintainerVersion, LibraryVersion> &GetVersions(void) { return _versions; }
		
		// get library name
		String const &GetName(void) const { return _name; }
		
		// get latest version available
		MaintainerVersion GetLatestVersion(void) const;
};

class LibrariesClass
{
	friend LibrariesClass &__GetLibraries(void);
	
	private:
	
		// available/installed libraries
		VectorMap<String, Library> _libraries;
		
		// constructor
		LibrariesClass();
		
	protected:
	
	public:
	
		// destructor
		~LibrariesClass();
		
		// clear data
		void Clear(void);

		// read from json file
		bool ParseJSON(String const &json);
		
		// scan from installed on disk
		bool ScanLocal(void);
		
		// refresh libraries
		bool Refresh(void);
		
		int GetCount(void) const { return _libraries.GetCount(); }
		Library &operator[](int i) { return _libraries[i]; }
		Library const &operator[](int i) const { return _libraries[i]; }
		String const &GetKey(int i) const { return _libraries.GetKey(i); }
		
		// find a library by name
		Library const *Find(String const &name) const;
		Library *Find(String const &name);
};

extern LibrariesClass &__GetLibraries(void);

#define Libraries __GetLibraries()

#endif
