// Copyright 2022, FOSS-VG Developers and Contributers
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, version 3.
//
// This program 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// version 3 along with this program.
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html

#include <iostream>
#include <cstdint>

int main() {
    uint32_t* testInteger = new uint32_t;
    *testInteger = 0x04030201;
    auto data = reinterpret_cast<std::uint8_t*>(testInteger);

    std::cout << "#pragma once" << std::endl;

    if (
        *data  ==  0x01 &&
        *(data+1)==0x02 &&
        *(data+2)==0x03 &&
        *(data+3)==0x04
    ) {
        std::cerr << "Little Endian" << std::endl;
        std::cout << "#define FOSSVG_LITTLE_ENDIAN" << std::endl;
    } else if (
        *data  ==  0x04 &&
        *(data+1)==0x03 &&
        *(data+2)==0x02 &&
        *(data+3)==0x01
    ) {
        std::cerr << "Big Endian" << std::endl;
        std::cout << "#define FOSSVG_BIG_ENDIAN" << std::endl;
    } else if (
        *data  ==  0x03 &&
        *(data+1)==0x04 &&
        *(data+2)==0x01 &&
        *(data+3)==0x02
    ) {
        std::cerr << "PDP Endian (Little Word)" << std::endl;
        std::cout << "#define FOSSVG_ENDIAN_LITTLE_WORD /* PDP-11-style byte-swapped words */" << std::endl;
    } else if (
        *data  ==  0x02 &&
        *(data+1)==0x01 &&
        *(data+2)==0x04 &&
        *(data+3)==0x03
    ) {
        std::cerr << "Honeywell Endian (Big Word)" << std::endl;
        std::cout << "#define FOSSVG_ENDIAN_BIG_WORD /* Honeywell-316-style byte-swapped words */" << std::endl;

    } else {
        std::cerr << "Unknown Endianness" << std::endl;
        std::cout << "#define FOSSVG_ENDIAN_UNKNOWN" << std::endl;
    }

    delete data;

    std::cerr << "WARNING: This test may be unreliable. If you encounter issues, check the endianness of your machine and set it manually. Bi-endianness is not supported." << std::endl;
    return 0;
}
