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


#include <eCxx/eCxx_MemoryCard.h>

#include "TestUtility.h"


//
// Helper functions
//
using FormatStrategy = eCxx::SlotFS::FormatStrategy;


static void dumpSlotSizeAndCount(eCxx::uint32_t sectorCount, FormatStrategy formatStrategy, eCxx::uint16_t minSlotCount, eCxx::uint16_t maxSlotCount)
{
    // Match the slot size and count
    eCxx::uint16_t slotSize;
    eCxx::uint16_t slotCount;

    if( !eCxx::SlotFS::matchSlotSizeAndCount(slotSize, slotCount, sectorCount, formatStrategy, minSlotCount, maxSlotCount) ) {
        printf("NO MATCH\n");
        return;
    }

    // Dump it
    if(formatStrategy == FormatStrategy::Balanced        ) printf("Balanced         : ");
    if(formatStrategy == FormatStrategy::MaximumSlotSize ) printf("MaximumSlotSize  : ");
    if(formatStrategy == FormatStrategy::MaximumSlotCount) printf("MaximumSlotCount : ");

    const eCxx::uint32_t slotSizeBytes = static_cast<eCxx::uint32_t>(slotSize) * 4UL * 1024UL * 1024UL;

    printf(
        "sectorCount = %10lu ; slotSize = %3u (%10lu bytes) ; slotCount = %4u\n",
        (unsigned long) sectorCount,
        (unsigned int ) slotSize,
        (unsigned long) slotSizeBytes,
        (unsigned int ) slotCount
    );
}


//
// Test application
//
int main()
{
    printf("\n8 MB\n");
    dumpSlotSizeAndCount(     15160, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(     15160, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(     15160, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n16 MB\n");
    dumpSlotSizeAndCount(     30320, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(     30320, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(     30320, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n32 MB\n");
    dumpSlotSizeAndCount(     60640, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(     60640, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(     60640, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n64 MB\n");
    dumpSlotSizeAndCount(    121280, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(    121280, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(    121280, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n128 MB\n");
    dumpSlotSizeAndCount(    242560, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(    242560, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(    242560, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n256 MB\n");
    dumpSlotSizeAndCount(    485120, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(    485120, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(    485120, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n512 MB\n");
    dumpSlotSizeAndCount(    970240, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(    970240, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(    970240, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n1 GB\n");
    dumpSlotSizeAndCount(   1940480, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(   1940480, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(   1940480, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n2 GB\n");
    dumpSlotSizeAndCount(   3880960, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(   3880960, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(   3880960, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n4 GB\n");
    dumpSlotSizeAndCount(   7761920, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(   7761920, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(   7761920, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n8 GB\n");
    dumpSlotSizeAndCount(  15523840, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(  15523840, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(  15523840, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n16 GB\n");
    dumpSlotSizeAndCount(  31047680, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(  31047680, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(  31047680, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n32 GB\n");
    dumpSlotSizeAndCount(  62095360, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(  62095360, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(  62095360, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n64 GB\n");
    dumpSlotSizeAndCount( 124190720, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount( 124190720, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount( 124190720, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n128 GB\n");
    dumpSlotSizeAndCount( 248381440, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount( 248381440, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount( 248381440, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n256 GB\n");
    dumpSlotSizeAndCount( 496762880, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount( 496762880, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount( 496762880, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n512 GB\n");
    dumpSlotSizeAndCount( 993525760, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount( 993525760, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount( 993525760, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n1 TB\n");
    dumpSlotSizeAndCount(1987051520, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(1987051520, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(1987051520, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n2 TB\n");
    dumpSlotSizeAndCount(3974103040, FormatStrategy::MaximumSlotSize,  0, 0);
    dumpSlotSizeAndCount(3974103040, FormatStrategy::Balanced,         0, 0);
    dumpSlotSizeAndCount(3974103040, FormatStrategy::MaximumSlotCount, 0, 0);

    printf("\n2 TB (manual slot count)\n");
    dumpSlotSizeAndCount(3974103040, FormatStrategy::MaximumSlotSize,  1, 8000);
    dumpSlotSizeAndCount(3974103040, FormatStrategy::Balanced,         1, 8000);
    dumpSlotSizeAndCount(3974103040, FormatStrategy::MaximumSlotCount, 1, 8000);

    printf("\n");

    return 0;
}
