#ifndef VENDOR_SAMSUNG_SECURITY_DRK_BYTES_H
#define VENDOR_SAMSUNG_SECURITY_DRK_BYTES_H

#include <stdint.h>

namespace vendor {
namespace samsung {
namespace hardware {
namespace security {
namespace drk {

typedef enum {
    BASE64_BASIC,
    BASE64_SAFE_ALPHABET,
    BASE64_TABLE_MAX,
} B64_CONVERT_TYPE;

class Bytes
{
private:
    uint8_t *data;
    uint32_t data_pos;
    uint32_t data_last_pos;
    const static uint32_t max_data_len = 0x100000;

public:
    Bytes();
    ~Bytes();

    /**
     * empty () reset and free member varibles, data, data_pos, and etc
     */
    void     empty();
    /**
     * lowerCase () convert Upper Case to Lower Case only
     */
    void     lowerCase();
    /**
     * delAtEnd () remove the last byte and decrease data_pos
     */
    void     delAtEnd();
    /**
     * setAt () assign a charactor value into index position value of data
     */
    int32_t  setAt(uint32_t index, uint8_t value);
    /**
     * getAt () get a charactor value from index position value of data
     */
    uint8_t  getAt(uint32_t index);

    /**
     * set () allocate buffer as much as length bytes
     */
    int32_t  set(uint32_t length);

    /**
     * set () allocate buffer as much as length bytes then copy value into member buffer
     */
    int32_t  set(uint8_t *src, uint32_t length);

    /**
     * setLength () just allocate buffer and set length.
     * However value is not set yet.
     */
    int32_t  setLength(uint32_t length);

    /**
     * length () return the length of actual data size.
     */
    uint32_t length() { return data_pos; };

    /**
     * maxLength () return the max length of allocated buffer.
     */
    uint32_t maxLength() { return data_last_pos; };

    operator uint8_t *() { return data; };
    operator char     *() { return (char *)data; };

    uint8_t& operator [](uint32_t index)
    {
        if (data_last_pos >= index) {
            return data[data_last_pos - 1];
        } else {
            return data[index];
        }
    }

    Bytes&   operator=(Bytes& in);

    /* en/decoder */
    int32_t  b64Encode(B64_CONVERT_TYPE type, Bytes& out);
    int32_t  b64Decode(B64_CONVERT_TYPE type, Bytes& out);
};

}  // namespace drk
}  // namespace security
}  // namespace hardware
}  // namespace samsung
}  // namespace vendor

#endif
