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

namespace id3BiosealCppWrapper
{

/**
 * Represents an extension.
 */
class Extension
{
private:
    ID3_BIOSEAL_EXTENSION handle_{};

public:
    Extension() {
        check_error(id3BiosealExtension_Initialize(&handle_));
    }

    virtual ~Extension() {
        if (handle_) {
            id3BiosealExtension_Dispose(&handle_);
        }
    }


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

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

    // public getters and setters
    /**
    * Gets the the extension name.
    * @param name [out] The extension name.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The extension name.
    */
    void getName(std::string & name) {
        int nameSize = -1;
        auto err = id3BiosealExtension_GetName(handle_, name.data(), &nameSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            name.resize(nameSize);
            err = id3BiosealExtension_GetName(handle_, name.data(), &nameSize);
            if (err == 0) { name.resize(nameSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the extension name.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The extension name.
    */
    std::string getName() {
        std::string name;
        getName(name);
        return name;
    }

    /**
    * Gets the gets a string list containing the keys in the dict.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Gets a string list containing the keys in the dict.
    */
    StringArray getKeys() {
        StringArray keys;
        check_error(id3BiosealExtension_GetKeys(handle_, keys));
        return keys;
    }

    // public methods
    /**
    * Gets an item of the Extension object.
    * @param key [in] Unique key of the  item to get.
    * @param item [out]  item to get.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval  item to get.
    */
    void get(const char *key, std::string & item) {
        int itemSize = -1;
        auto err = id3BiosealExtension_Get(handle_, key, item.data(), &itemSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            item.resize(itemSize);
            err = id3BiosealExtension_Get(handle_, key, item.data(), &itemSize);
            if (err == 0) { item.resize(itemSize); }
        }
        check_error(err);
    }

    /**
    * Gets an item of the Extension object.
    * @param key [in] Unique key of the  item to get.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval  item to get.
    */
    std::string get(const char *key) {
        std::string item;
        get(key, item);
        return item;
    }

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

    /**
    * Determines whether the Extensionobject contains the specified key.
    * @param key [in] The key to locate in the  object.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval true if the  object contains an element with the specified key, otherwise false.
    */
    bool containsKey(const char *key) {
        bool result;
        check_error(id3BiosealExtension_ContainsKey(handle_, key, &result));
        return result;
    }

};
};