/*
 * Copyright (C) 2020-2021 Aloysius Indrayanto
 *
 * This file is part of the eCxx library, see LICENSE file for the license details.
 */

/*
 * ----------------------------------------------------------------------------------
 * The code in this file is copied (with a slight modifications) from:
 *     md5.h        - exposed md5 ROM functions for esp8266
 *     MD5Builder.h - exposed md5 ROM functions for esp8266
 * ----------------------------------------------------------------------------------
 * Copyright (C) 2015 Hristo Gochkov. All rights reserved.
 *
 * This file is part of the esp8266 core for Arduino environment.
 *
 * This library is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any later
 * version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 * ----------------------------------------------------------------------------------
 */


#ifndef ECXX_PLATFORM_NODEMCU_MD5_BUILDER_H
#define ECXX_PLATFORM_NODEMCU_MD5_BUILDER_H


#include "Stream.h"


//
// From esp8266 ROM
//
extern "C" {

    struct MD5Context {
        eCxx::uint32_t state[4];
        eCxx::uint32_t count[2];
        eCxx::uint8_t  buffer[64];
    };

    extern void MD5Init(MD5Context*);
    extern void MD5Update(MD5Context*, const eCxx::uint8_t*, eCxx::uint16_t);
    extern void MD5Final(eCxx::uint8_t[16], MD5Context*);

} // extern "C"


namespace eCxx {

namespace NodeMCU {


//
// MD5 builder class
//
class MD5Builder {
    public:
        void begin();

        void add(const uint8_t* data, const uint16_t len);
        void addHexString(const char* data);
        bool addStream(Stream & stream, const size_t maxLen);

        void calculate();

        void getBytes(uint8_t* output) const;
        void getChars(char* output) const;
        const WString toString() const;

        inline void add(const char* data)
        { add( reinterpret_cast<const uint8_t*>(data), strlen(data) ); }

        inline void add(char* data)
        { add( reinterpret_cast<const char*>(data) ); }

        inline void add(const WString& data)
        { add( data.c_str() ); }

        inline void addHexString(char* data)
        { addHexString( reinterpret_cast<const char*>(data) ); }

        inline void addHexString(const WString& data)
        { addHexString( data.c_str() ); }

    private:
        MD5Context _ctx;
        uint8_t    _buf[16];
};


} // namespace NodeMCU

} // namespace eCxx


//
// For compatibility with the Arduino library part
//
typedef eCxx::NodeMCU::MD5Builder MD5Builder;


#endif
