/**
 * @file    drive.h
 * @brief   represent physical drive
 * @author  hendrik schutter
 * @date    01.05.2020
 */

#ifndef DRIVE_H_
#define DRIVE_H_

#include "reHDD.h"

class Drive
{

public:
    enum TaskState
    {
        NONE,
        SHRED_SELECTED,
        SHRED_ACTIVE, // shred iterations active
        CHECK_ACTIVE, // optional checking active
        DELETE_SELECTED,
        DELETE_ACTIVE,
        FROZEN
    } state;

    struct
    {
        time_t u32ShredTimeDelta;
        std::chrono::time_point<std::chrono::system_clock> chronoShredTimestamp;
        unsigned long ulWrittenBytes;
        unsigned long ulSpeedMetricBytesWritten;
    } sShredSpeed;

    bool bWasShredded = false; // all shred iterations done
    bool bWasChecked = false;  // all shred iterations and optional checking done
    bool bWasDeleted = false;
    bool bIsOffline = false;
    uint32_t u32DriveChecksumAfterShredding = 0U;

private:
    string sPath;
    time_t u32Timestamp = 0U;          // unix timestamp for detecting a frozen drive
    double d32TaskPercentage = 0U;     // in percent for Shred (1 to 100)
    time_t u32TimestampTaskStart = 0U; // unix timestamp for duration of an action
    time_t u32TaskDuration = 0U;       // time needed to complete the task

    struct
    {
        string sModelFamily;
        string sModelName;
        string sSerial;
        uint64_t u64Capacity = 0U; // in byte
        uint32_t u32ErrorCount = 0U;
        uint32_t u32PowerOnHours = 0U; // in hours
        uint32_t u32PowerCycles = 0U;
        uint32_t u32Temperature = 0U; // in Fahrenheit, just kidding: degree Celsius
    } sSmartData;

private:
    void setTimestamp();

protected:
public:
    Drive(string path)
    {
        this->sPath = path;
    }

    string getPath(void);
    string getModelFamily(void);
    string getModelName(void);
    string getSerial(void);
    uint64_t getCapacity(void); // in byte
    uint32_t getErrorCount(void);
    uint32_t getPowerOnHours(void); // in hours
    uint32_t getPowerCycles(void);
    uint32_t getTemperature(void); // in Fahrenheit, just kidding: degree Celsius
    void checkFrozenDrive(void);

    void setDriveSMARTData(string modelFamily,
                           string modelName,
                           string serial,
                           uint64_t capacity,
                           uint32_t errorCount,
                           uint32_t powerOnHours,
                           uint32_t powerCycles,
                           uint32_t temperature);

    string sCapacityToText();
    string sErrorCountToText();
    string sPowerOnHoursToText();
    string sPowerCyclesToText();
    string sTemperatureToText();

    void setTaskPercentage(double d32TaskPercentage);
    double getTaskPercentage(void);

    void setActionStartTimestamp();
    time_t getActionStartTimestamp();

    void calculateTaskDuration();
    time_t getTaskDuration();
};

#endif // DRIVE_H_