#pragma once
#ifdef DLL_EXPORT
#define DLL_API __declspec(dllexport)
#else
#define DLL_API  __declspec(dllimport)
#endif
#include <ctime>
#include <string>
#include <vector>
#include "SMBiosEnums.h"
struct innerBiosInformation;
struct innerSystemEnclosure;
struct innerSMBios;
struct innerSystemInformation;
struct innerBaseBoardInformation;
struct innerProcessorInformation;
struct innerCacheInformation;
struct innerMemoryDevice;
struct innerSMBios;

class DLL_API BiosInformation {
public:
    BiosInformation(std::shared_ptr<innerBiosInformation> inner);
    ~BiosInformation();

    bool isNull() const;
    time_t getDate();
    std::string getVendor();
    std::string getVersion();
    unsigned long long getSize();
private:
    std::shared_ptr<innerBiosInformation> inner;
};

class DLL_API SystemInformation {
public:
    SystemInformation(std::shared_ptr<innerSystemInformation> inner);
    ~SystemInformation();
    bool isNull() const;
    std::string getFamily();
    std::string getManufacturerName();
    std::string getProductName();
    std::string getSerialNumber();
    std::string getVersion();
    SystemWakeUp WakeUp();
private:
    std::shared_ptr<innerSystemInformation> inner;
};

class DLL_API SystemEnclosure {
public:
    SystemEnclosure(std::shared_ptr<innerSystemEnclosure> inner);
    ~SystemEnclosure();

    bool isNull() const;


    std::string getAssetTag();

    SystemEnclosureState getBootUpState();

    bool getLockDetected();
    void setLockDetected(bool locked);

    std::string getManufacturerName();

 
    unsigned char getPowerCords();

    SystemEnclosureState getPowerSupplyState();

    unsigned char getRackHeight();

    SystemEnclosureSecurityStatus getSecurityStatus();
    void setSecurityStatus(SystemEnclosureSecurityStatus status);

    std::string getSerialNumber();

    std::string getSKU();

    SystemEnclosureState getThermalState();

    SystemEnclosureType getType();

    std::string Version();
private:
    std::shared_ptr<innerSystemEnclosure> inner;
};

class DLL_API BaseBoardInformation {
public:
    BaseBoardInformation(std::shared_ptr<innerBaseBoardInformation> inner);
    ~BaseBoardInformation();

    bool isNull() const;

    std::string getManufacturerName();
    std::string getProductName();
    std::string getSerialNumber();
    std::string getVersion();
private:
    std::shared_ptr<innerBaseBoardInformation> inner;
};

class DLL_API CSProcessorInformation {
public:
    CSProcessorInformation(std::shared_ptr<innerProcessorInformation> inner);
    ~CSProcessorInformation();

    bool isNull() const;

    ProcessorCharacteristics getCharacteristics();
    unsigned short getCoreCount();
    unsigned short getCoreEnabled();
    unsigned short getCurrentSpeed();
    unsigned short getExternalClock();
    ProcessorFamily getFamily();
    unsigned short getHandle();
    unsigned long long getId();
    unsigned short getL1CacheHandle();
    unsigned short getL2CacheHandle();
    unsigned short getL3CacheHandle();
    std::string getManufacturerName();
    unsigned short getMaxSpeed();
    ProcessorType getProcessorType();
    std::string getSerial();
    ProcessorSocket getSocket();
    std::string getSocketDesignation();
    unsigned short getThreadCount();
    std::string getVersion();
    
private:
    std::shared_ptr<innerProcessorInformation> inner;
};
class DLL_API CacheInformation
{
public:
    CacheInformation(std::shared_ptr<innerCacheInformation> inner);
    ~CacheInformation();

    bool isNull() const;

    CacheAssociativity getAssociativity();
    CacheDesignation getDesignation();
    unsigned short getHandle();
    unsigned short getSize();

private:
    std::shared_ptr<innerCacheInformation> inner;
};
class DLL_API MemoryDevice
{
public:
    MemoryDevice(std::shared_ptr<innerMemoryDevice> inner);
    ~MemoryDevice();

    bool isNull() const;

    std::string getBankLocator();
    std::string getDeviceLocator();
    std::string getManufacturerName();
    std::string getPartNumber();
    std::string getSerialNumber();
    unsigned int getSize();
    unsigned short getSpeed();
    unsigned short getConfiguredSpeed();
    unsigned short getConfiguredVoltage();
    MemoryType getType();

private:
    std::shared_ptr<innerMemoryDevice> inner;

};

class DLL_API SMBios
{
public:
    SMBios();
    ~SMBios();

    bool isNull() const;

    SMBios(std::shared_ptr<innerSMBios>);
    bool operator==(const SMBios& other) const;
    BiosInformation getBios();
    BaseBoardInformation getBoard();
    std::vector<MemoryDevice> getMemoryDevice();
    std::vector<CacheInformation> getProcessorCaches();
    std::vector<CSProcessorInformation> getProcessors();
    SystemInformation getSystem();
    SystemEnclosure getSystemEnclosure();
    std::string getGetReport();
private:
    std::shared_ptr<innerSMBios> inner;
};
