import { detachArrayBuffer } from '../helpers/detach-array-buffer';
import { wrapAudioBufferGetChannelDataMethod } from '../helpers/wrap-audio-buffer-get-channel-data-method';
export const createDecodeAudioData = (audioBufferStore, cacheTestResult, createDataCloneError, createEncodingError, detachedArrayBuffers, getNativeContext, isNativeContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, testPromiseSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds) => {
    return (anyContext, audioData) => {
        const nativeContext = isNativeContext(anyContext) ? anyContext : getNativeContext(anyContext);
        // Bug #43: Only Chrome and Edge do throw a DataCloneError.
        if (detachedArrayBuffers.has(audioData)) {
            const err = createDataCloneError();
            return Promise.reject(err);
        }
        // The audioData parameter maybe of a type which can't be added to a WeakSet.
        try {
            detachedArrayBuffers.add(audioData);
        }
        catch {
            // Ignore errors.
        }
        // Bug #21: Safari does not support promises yet.
        if (cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeContext))) {
            return nativeContext.decodeAudioData(audioData).then((audioBuffer) => {
                // Bug #133: Safari does neuter the ArrayBuffer.
                detachArrayBuffer(audioData).catch(() => {
                    // Ignore errors.
                });
                // Bug #157: Firefox does not allow the bufferOffset to be out-of-bounds.
                if (!cacheTestResult(testAudioBufferCopyChannelMethodsOutOfBoundsSupport, () => testAudioBufferCopyChannelMethodsOutOfBoundsSupport(audioBuffer))) {
                    wrapAudioBufferCopyChannelMethodsOutOfBounds(audioBuffer);
                }
                audioBufferStore.add(audioBuffer);
                return audioBuffer;
            });
        }
        // Bug #21: Safari does not return a Promise yet.
        return new Promise((resolve, reject) => {
            const complete = async () => {
                // Bug #133: Safari does neuter the ArrayBuffer.
                try {
                    await detachArrayBuffer(audioData);
                }
                catch {
                    // Ignore errors.
                }
            };
            const fail = (err) => {
                reject(err);
                complete();
            };
            // Bug #26: Safari throws a synchronous error.
            try {
                // Bug #1: Safari requires a successCallback.
                nativeContext.decodeAudioData(audioData, (audioBuffer) => {
                    // Bug #5: Safari does not support copyFromChannel() and copyToChannel().
                    // Bug #100: Safari does throw a wrong error when calling getChannelData() with an out-of-bounds value.
                    if (typeof audioBuffer.copyFromChannel !== 'function') {
                        wrapAudioBufferCopyChannelMethods(audioBuffer);
                        wrapAudioBufferGetChannelDataMethod(audioBuffer);
                    }
                    audioBufferStore.add(audioBuffer);
                    complete().then(() => resolve(audioBuffer));
                }, (err) => {
                    // Bug #4: Safari returns null instead of an error.
                    if (err === null) {
                        fail(createEncodingError());
                    }
                    else {
                        fail(err);
                    }
                });
            }
            catch (err) {
                fail(err);
            }
        });
    };
};
//# sourceMappingURL=decode-audio-data.js.map