//--------------------------------------------------------------------------------------------------
// Copyright (c) id3 Technologies
// All Rights Reserved.
//--------------------------------------------------------------------------------------------------
#pragma once
#include <id3BiosealCppWrapper/id3BiosealException.hpp>
#include <id3BiosealCppWrapper/id3BiosealLogItem.hpp>
#include <id3Bioseal/id3BiosealLog.h>

namespace id3BiosealCppWrapper
{

/**
 * Represents the log.
 */
class Log
{
private:
    ID3_BIOSEAL_LOG handle_{};

public:
    Log() {
        check_error(id3BiosealLog_Initialize(&handle_));
    }

    virtual ~Log() {
        if (handle_) {
            id3BiosealLog_Dispose(&handle_);
        }
    }


    Log(Log &&src) noexcept: handle_(src.handle_) {
        src.handle_ = nullptr;
    }

    ID3_BIOSEAL_LOG getHandle() const { return handle_; }
    operator ID3_BIOSEAL_LOG () const { return handle_; }

    // --- Iterator Support ---
    class iterator {
    private:
        Log *list_;
        int index_;
    public:
        iterator(Log *list, int index) : list_(list), index_(index) {}

        LogItem operator*() const
        { return list_->get(index_); }

        iterator &operator++() {
            ++index_;
            return *this;
        }

        bool operator!=(const iterator &src) const
        { return index_ != src.index_; }
    };

    iterator begin()
    { return iterator(this, 0); }

    iterator end()
    { return iterator(this, getCount()); }

    // public getters and setters
    // public methods
    /**
    * Gets an item of the Log object.
    * @param index [in] Index of the LogItem item to get.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval LogItem item to get.
    */
    LogItem get(int index) {
        LogItem log_item_item;
        check_error(id3BiosealLog_Get(handle_, index, log_item_item));
        return log_item_item;
    }

    /**
    * Gets the number of elements in the Log object.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Number of elements in the LogItem object.
    */
    int getCount() {
        int count;
        check_error(id3BiosealLog_GetCount(handle_, &count));
        return count;
    }

    /**
    * Exports a representation of the log, in JSON format.
    * @param indentation [in] The indentation of the json string.
    * @param debug [in] Indicates whether debug information is added to the log.
    * @param result [out] The result.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The result.
    */
    void exportToJson(const char *indentation, bool debug, std::string & result) {
        int resultSize = -1;
        auto err = id3BiosealLog_ExportToJson(handle_, indentation, debug, result.data(), &resultSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            result.resize(resultSize);
            err = id3BiosealLog_ExportToJson(handle_, indentation, debug, result.data(), &resultSize);
            if (err == 0) { result.resize(resultSize); }
        }
        check_error(err);
    }

    /**
    * Exports a representation of the log, in JSON format.
    * @param indentation [in] The indentation of the json string.
    * @param debug [in] Indicates whether debug information is added to the log.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The result.
    */
    std::string exportToJson(const char *indentation, bool debug) {
        std::string result;
        exportToJson(indentation, debug, result);
        return result;
    }

    /**
    * Exports a representation of the log, in HTML format.
    * @param debug [in] Indicates whether debug information is added to the log.
    * @param result [out] The result.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The result.
    */
    void exportToHtml(bool debug, std::string & result) {
        int resultSize = -1;
        auto err = id3BiosealLog_ExportToHtml(handle_, debug, result.data(), &resultSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            result.resize(resultSize);
            err = id3BiosealLog_ExportToHtml(handle_, debug, result.data(), &resultSize);
            if (err == 0) { result.resize(resultSize); }
        }
        check_error(err);
    }

    /**
    * Exports a representation of the log, in HTML format.
    * @param debug [in] Indicates whether debug information is added to the log.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The result.
    */
    std::string exportToHtml(bool debug) {
        std::string result;
        exportToHtml(debug, result);
        return result;
    }

};
};