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


#include <eCxx/eCxx.h>

#include "NodeMCU_Common.h"


//
// Include common source code for HWInfo test application
//
#include "../CommonCode/HWInfo_Common.h"


//
// The init function
//
void eCxx_user_init()
{
    // Initialize application
    initBasicNodeMCUApp();

    // There is no need to enable the 74LVC541 buffers on the eCxx NodeMCU development board because
    // the UART is only used for communication with the host PC

    // Initialize UART and print common hardware information
    auto& u = initUARTAndPrintCommonHWInfo();

    // Print platform-specific hardware information
    u.writeString( PGM_STR("IRAM   size             (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::iramSize                (), 9          );
    u.writeString( PGM_STR("ICACHE size             (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::icacheSize              (), 9          );
    u.write      ( '\n'                                          );
    App::yield();
    u.writeString( PGM_STR("Free CONT stack         (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::freeContStack           (), 9          );
    u.writeString( PGM_STR("Free heap size          (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::freeHeapSize            (), 9          );
    u.writeString( PGM_STR("Maximum free block size (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::maxHeapFreeBlockSize    (), 9          );
    u.writeString( PGM_STR("Heap framentation       (%    ) : ") ); u.writeDecStringln   ( eCxx::HWInfo::percentHeapFragmentation(), 9          );
    u.write      ( '\n'                                          );
    u.writeString( PGM_STR("User program size       (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::userProgramSize         (), 9          );
    u.writeString( PGM_STR("Free user program space (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::freeUserProgramSpace    (), 9          );
    u.write      ( '\n'                                          );
    App::yield();
    u.writeString( PGM_STR("Flash chip identification       : ") ); u.writeHexSeqStringln( eCxx::HWInfo::flashChipId             (), true, true );
    u.writeString( PGM_STR("Flash chip speed        ( Hz  ) : ") ); u.writeDecStringln   ( eCxx::HWInfo::flashChipSpeed          (), 9          );
    u.writeString( PGM_STR("Flash chip speed        (MHz  ) : ") ); u.writeDecStringln   ( eCxx::HWInfo::flashChipSpeed_MHz      (), 9          );
    u.writeString( PGM_STR("Flash chip mode                 : ") ); u.writeStringln      ( eCxx::HWInfo::flashChipMode           ()             );
    u.writeString( PGM_STR("Flash chip map                  : ") ); u.writeStringln      ( eCxx::HWInfo::flashChipMap            ()             );
    u.write      ( '\n'                                          );
    App::yield();
    u.writeString( PGM_STR("Boot version                    : ") ); u.writeDecStringln   ( eCxx::HWInfo::bootVersion             ()             );
    u.writeString( PGM_STR("SDK version                     : ") ); u.writeStringln      ( eCxx::HWInfo::sdkVersion              ()             );
    u.writeString( PGM_STR("Bit size of time_t      (bits ) : ") ); u.writeDecStringln   ( eCxx::HWInfo::time_tBitSize           ()             );
    u.write      ( '\n'                                          );
    App::yield();
    u.writeString( PGM_STR("Boot mode                       : ") ); u.writeDecStringln   ( eCxx::HWInfo::bootMode                ()             );
    u.writeString( PGM_STR("Reset reason                    : ") ); u.writeStringln      ( eCxx::HWInfo::resetReason             ()             );
    u.write      ( '\n'                                          );
    u.writeString( PGM_STR("MAC address                     : ") ); u.writeHexSeqStringln( eCxx::HWInfo::macAddress(),           6,  true, true );
    u.write      ( '\n'                                          );
    App::yield();

    // Get network interface description list
    App::NetIfDesc nid[4];
    const size_t nic = App::getNetIfDescList( nid, eCxx::arraySize(nid) );

    u.writeStringln( PGM_STR("List of network interface(s)    : \n") );
    App::yield();
    for(size_t i = 0; i < nic; ++i) {
        u.writeString( PGM_STR("    Interface number      = ") ); u.writeDecStringln(             nid[i].ifNumber   );
        u.writeString( PGM_STR("    Interface name        = ") ); u.writeStringln   (             nid[i].ifName     );
        u.writeString( PGM_STR("    Interface hostname    = ") ); u.writeStringln   (             nid[i].ifHostname );
        u.writeString( PGM_STR("    Interface MAC address = ") ); u.writeStringln   (             nid[i].ifMAC      );
        App::yield();
        u.writeString( PGM_STR("    Is link up            = ") ); u.writeStringln   ( eCxx::Bool( nid[i].isLinkUp ) );
        u.writeString( PGM_STR("    Is local              = ") ); u.writeStringln   ( eCxx::Bool( nid[i].isLocal  ) );
        u.writeString( PGM_STR("    Is legacy             = ") ); u.writeStringln   ( eCxx::Bool( nid[i].isLegacy ) );
        u.writeString( PGM_STR("    Is IPv6               = ") ); u.writeStringln   ( eCxx::Bool( nid[i].isIPv6   ) );
        App::yield();
        u.writeString( PGM_STR("    IP address            = ") ); u.writeStringln   (             nid[i].address    );
        u.writeString( PGM_STR("    Network mask          = ") ); u.writeStringln   (             nid[i].netmask    );
        u.writeString( PGM_STR("    Gateway               = ") ); u.writeStringln   (             nid[i].gateway    );
        u.write('\n');
        App::yield();
    }

#ifdef ECXX_HAVE_PROGRAM_STRING_LITERALS
    // Test string literals in program memory by using literal operators for string literals
    testProgramStringLiterals(u);
#endif
}


//
// The task function
//
void eCxx_user_task()
{
    // Process event
    eCxx::Application::processEvent();
}
