/*
  Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely.
*/

#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_test.h>

static void log_usage(char *progname, SDLTest_CommonState *state) {
    static const char *options[] = { "in.wav", "out.wav", "newfreq", "newchan", NULL };
    SDLTest_CommonLogUsage(state, progname, options);
}

int main(int argc, char **argv)
{
    SDL_AudioSpec spec;
    SDL_AudioSpec cvtspec;
    SDL_AudioStream *stream = NULL;
    Uint8 *dst_buf = NULL;
    Uint32 len = 0;
    Uint8 *data = NULL;
    int bitsize = 0;
    int blockalign = 0;
    int avgbytes = 0;
    SDL_IOStream *io = NULL;
    int dst_len;
    int ret = 0;
    int argpos = 0;
    int i;
    SDLTest_CommonState *state;
    char *file_in = NULL;
    char *file_out = NULL;

    /* Initialize test framework */
    state = SDLTest_CommonCreateState(argv, 0);
    if (!state) {
        return 1;
    }

    SDL_zero(cvtspec);

    /* Parse commandline */
    for (i = 1; i < argc;) {
        int consumed;

        consumed = SDLTest_CommonArg(state, i);
        if (!consumed) {
            if (argpos == 0) {
                file_in = argv[i];
                argpos++;
                consumed = 1;
            } else if (argpos == 1) {
                file_out = argv[i];
                argpos++;
                consumed = 1;
            } else if (argpos == 2) {
                char *endp;
                cvtspec.freq  = (int)SDL_strtoul(argv[i], &endp, 0);
                if (endp != argv[i] && *endp == '\0') {
                    argpos++;
                    consumed = 1;
                }
            } else if (argpos == 3) {
                char *endp;
                cvtspec.channels = (int)SDL_strtoul(argv[i], &endp, 0);
                if (endp != argv[i] && *endp == '\0') {
                    argpos++;
                    consumed = 1;
                }
            }
        }
        if (consumed <= 0) {
            log_usage(argv[0], state);
            ret = 1;
            goto end;
        }

        i += consumed;
    }

    if (argpos != 4) {
        log_usage(argv[0], state);
        ret = 1;
        goto end;
    }

    if (!SDL_Init(SDL_INIT_AUDIO)) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init() failed: %s", SDL_GetError());
        ret = 2;
        goto end;
    }

    if (!SDL_LoadWAV(file_in, &spec, &data, &len)) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "failed to load %s: %s", file_in, SDL_GetError());
        ret = 3;
        goto end;
    }

    cvtspec.format = spec.format;
    if (!SDL_ConvertAudioSamples(&spec, data, len, &cvtspec, &dst_buf, &dst_len)) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "failed to convert samples: %s", SDL_GetError());
        ret = 4;
        goto end;
    }

    /* write out a WAV header... */
    io = SDL_IOFromFile(file_out, "wb");
    if (!io) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "opening '%s' failed: %s", file_out, SDL_GetError());
        ret = 5;
        goto end;
    }

    bitsize = SDL_AUDIO_BITSIZE(spec.format);
    blockalign = (bitsize / 8) * cvtspec.channels;
    avgbytes = cvtspec.freq * blockalign;

    SDL_WriteU32LE(io, 0x46464952); /* RIFF */
    SDL_WriteU32LE(io, dst_len + 36);
    SDL_WriteU32LE(io, 0x45564157);                             /* WAVE */
    SDL_WriteU32LE(io, 0x20746D66);                             /* fmt */
    SDL_WriteU32LE(io, 16);                                     /* chunk size */
    SDL_WriteU16LE(io, SDL_AUDIO_ISFLOAT(spec.format) ? 3 : 1); /* uncompressed */
    SDL_WriteU16LE(io, (Uint16)cvtspec.channels);               /* channels */
    SDL_WriteU32LE(io, cvtspec.freq);                           /* sample rate */
    SDL_WriteU32LE(io, avgbytes);                               /* average bytes per second */
    SDL_WriteU16LE(io, (Uint16)blockalign);                     /* block align */
    SDL_WriteU16LE(io, (Uint16)bitsize);                        /* significant bits per sample */
    SDL_WriteU32LE(io, 0x61746164);                             /* data */
    SDL_WriteU32LE(io, dst_len);                                /* size */
    SDL_WriteIO(io, dst_buf, dst_len);

    if (!SDL_CloseIO(io)) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "closing '%s' failed: %s", file_out, SDL_GetError());
        ret = 6;
        goto end;
    }

end:
    SDL_free(dst_buf);
    SDL_free(data);
    SDL_DestroyAudioStream(stream);
    SDL_Quit();
    SDLTest_CommonDestroyState(state);
    return ret;
}
