#include <cstddef>
#include <cstdint>

#include <fuzzing/datasource/datasource.hpp>
#include <fuzzing/memory.hpp>

#include "FLAC++/decoder.h"

template <> FLAC__MetadataType fuzzing::datasource::Base::Get<FLAC__MetadataType>(const uint64_t id) {
    (void)id;
    switch ( Get<uint8_t>() ) {
        case 0:
            return FLAC__METADATA_TYPE_STREAMINFO;
        case 1:
            return FLAC__METADATA_TYPE_PADDING;
        case 2:
            return FLAC__METADATA_TYPE_APPLICATION;
        case 3:
            return FLAC__METADATA_TYPE_SEEKTABLE;
        case 4:
            return FLAC__METADATA_TYPE_VORBIS_COMMENT;
        case 5:
            return FLAC__METADATA_TYPE_CUESHEET;
        case 6:
            return FLAC__METADATA_TYPE_PICTURE;
        case 7:
            return FLAC__METADATA_TYPE_UNDEFINED;
        case 8:
            return FLAC__MAX_METADATA_TYPE;
        default:
            return FLAC__METADATA_TYPE_STREAMINFO;
    }
}

namespace FLAC {
	namespace Decoder {
        class FuzzerStream : public Stream {
            private:
                fuzzing::datasource::Datasource& ds;
            public:
                FuzzerStream(fuzzing::datasource::Datasource& dsrc) :
                    Stream(), ds(dsrc) { }

                ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes)  override {
                    try {
                        const size_t maxCopySize = *bytes;

                        if ( maxCopySize > 0 ) {
                            /* memset just to test if this overwrites anything, and triggers ASAN */
                            memset(buffer, 0, maxCopySize);
                        }

                        const auto data = ds.GetData(0);
                        const auto dataSize = data.size();
                        const auto copySize = std::min(maxCopySize, dataSize);

                        if ( copySize > 0 ) {
                            memcpy(buffer, data.data(), copySize);
                        }

                        *bytes = copySize;

                        return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
                    } catch ( ... ) {
	                    return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
                    }
                }

                ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[])  override {
                    {
                        fuzzing::memory::memory_test(&(frame->header), sizeof(frame->header));
                        fuzzing::memory::memory_test(&(frame->footer), sizeof(frame->footer));
                    }

                    {
                        const auto numChannels = get_channels();
                        const size_t bytesPerChannel = frame->header.blocksize * sizeof(FLAC__int32);
                        for (size_t i = 0; i < numChannels; i++) {
                            fuzzing::memory::memory_test(buffer[i], bytesPerChannel);
                        }
                    }

                    try {
                        if ( ds.Get<bool>() == true ) {
	                        return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
                        }
                    } catch ( ... ) { }
                    return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
                }

                void error_callback(::FLAC__StreamDecoderErrorStatus status)  override {
                    fuzzing::memory::memory_test(status);
                }

                void metadata_callback(const ::FLAC__StreamMetadata *metadata) override {
                    fuzzing::memory::memory_test(metadata->type);
                    fuzzing::memory::memory_test(metadata->is_last);
                    fuzzing::memory::memory_test(metadata->length);
                    fuzzing::memory::memory_test(metadata->data);
                }

                ::FLAC__StreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset) override {
                    fuzzing::memory::memory_test(absolute_byte_offset);

                    try {
                        if ( ds.Get<bool>() == true ) {
                            return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
                        } else {
                            return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
                        }
                    } catch ( ... ) {
                        return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
                    }
                }
#if 0
                ::FLAC__StreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset) override {
                    fuzzing::memory::memory_test(*absolute_byte_offset);

                    try {
                        if ( ds.Get<bool>() == true ) {
                            return FLAC__STREAM_DECODER_TELL_STATUS_OK;
                        } else {
                            return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
                        }
                    } catch ( ... ) {
                        return FLAC__STREAM_DECODER_TELL_STATUS_OK;
                    }
                }

                ::FLAC__StreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length) override {
                    fuzzing::memory::memory_test(*stream_length);

                    try {
                        if ( ds.Get<bool>() == true ) {
                            return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
                        } else {
                            return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
                        }
                    } catch ( ... ) {
                        return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
                    }
                }
#endif
        };
    }
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    fuzzing::datasource::Datasource ds(data, size);
    FLAC::Decoder::FuzzerStream decoder(ds);

    try {
        {
            ::FLAC__StreamDecoderInitStatus ret;

            if ( ds.Get<bool>() ) {
                ret = decoder.init();
            } else {
                ret = decoder.init_ogg();
            }

            if ( ret != FLAC__STREAM_DECODER_INIT_STATUS_OK ) {
                goto end;
            }
        }

        if ( ds.Get<bool>() ) {
#ifdef FUZZER_DEBUG
            printf("set_ogg_serial_number\n");
#endif
            decoder.set_ogg_serial_number(ds.Get<long>());
        }
        if ( ds.Get<bool>() ) {
#ifdef FUZZER_DEBUG
            printf("set_md5_checking\n");
#endif
            decoder.set_md5_checking(ds.Get<bool>());
        }
        if ( ds.Get<bool>() ) {
#ifdef FUZZER_DEBUG
            printf("set_metadata_respond\n");
#endif
            decoder.set_metadata_respond(ds.Get<::FLAC__MetadataType>());
        }
        if ( ds.Get<bool>() ) {
            const auto idVector = ds.GetData(0);
            unsigned char id[4];
            if ( idVector.size() >= sizeof(id) ) {
                memcpy(id, idVector.data(), sizeof(id));
#ifdef FUZZER_DEBUG
                printf("set_metadata_respond_application\n");
#endif
                decoder.set_metadata_respond_application(id);
            }
        }
        if ( ds.Get<bool>() ) {
#ifdef FUZZER_DEBUG
            printf("set_metadata_respond_all\n");
#endif
            decoder.set_metadata_respond_all();
        }
        if ( ds.Get<bool>() ) {
#ifdef FUZZER_DEBUG
            printf("set_metadata_ignore\n");
#endif
            decoder.set_metadata_ignore(ds.Get<::FLAC__MetadataType>());
        }
        if ( ds.Get<bool>() ) {
            const auto idVector = ds.GetData(0);
            unsigned char id[4];
            if ( idVector.size() >= sizeof(id) ) {
                memcpy(id, idVector.data(), sizeof(id));
#ifdef FUZZER_DEBUG
                printf("set_metadata_ignore_application\n");
#endif
                decoder.set_metadata_ignore_application(id);
            }
        }
        if ( ds.Get<bool>() ) {
#ifdef FUZZER_DEBUG
            printf("set_metadata_ignore_all\n");
#endif
            decoder.set_metadata_ignore_all();
        }

        while ( ds.Get<bool>() ) {
            switch ( ds.Get<uint8_t>() ) {
                case    0:
                    {
#ifdef FUZZER_DEBUG
                        printf("flush\n");
#endif
                        const bool res = decoder.flush();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    1:
                    {
#ifdef FUZZER_DEBUG
                        printf("reset\n");
#endif
                        const bool res = decoder.reset();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    2:
                    {
#ifdef FUZZER_DEBUG
                        printf("process_single\n");
#endif
                        const bool res = decoder.process_single();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    3:
                    {
#ifdef FUZZER_DEBUG
                        printf("process_until_end_of_metadata\n");
#endif
                        const bool res = decoder.process_until_end_of_metadata();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    4:
                    {
#ifdef FUZZER_DEBUG
                        printf("process_until_end_of_stream\n");
#endif
                        const bool res = decoder.process_until_end_of_stream();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    5:
                    {
#ifdef FUZZER_DEBUG
                        printf("skip_single_frame\n");
#endif
                        const bool res = decoder.skip_single_frame();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    6:
                    {
#ifdef FUZZER_DEBUG
                        printf("seek_absolute\n");
#endif
                        const bool res = decoder.seek_absolute(ds.Get<uint64_t>());
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    7:
                    {
#ifdef FUZZER_DEBUG
                        printf("get_md5_checking\n");
#endif
                        const bool res = decoder.get_md5_checking();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    8:
                    {
#ifdef FUZZER_DEBUG
                        printf("get_total_samples\n");
#endif
                        const bool res = decoder.get_total_samples();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    9:
                    {
#ifdef FUZZER_DEBUG
                        printf("get_channels\n");
#endif
                        const bool res = decoder.get_channels();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    10:
                    {
#ifdef FUZZER_DEBUG
                        printf("get_bits_per_sample\n");
#endif
                        const bool res = decoder.get_bits_per_sample();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    11:
                    {
#ifdef FUZZER_DEBUG
                        printf("get_sample_rate\n");
#endif
                        const bool res = decoder.get_sample_rate();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
                case    12:
                    {
#ifdef FUZZER_DEBUG
                        printf("get_blocksize\n");
#endif
                        const bool res = decoder.get_blocksize();
                        fuzzing::memory::memory_test(res);
                    }
                    break;
            }
        }
    } catch ( ... ) { }

end:
    {
        const bool res = decoder.finish();
        fuzzing::memory::memory_test(res);
    }
    return 0;
}
