# Copyright (C) 2015 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import struct
import wave

from webkitcorepy import BytesIO, StringIO


class WaveDiff(object):
    _paramNames = ('Number of channels', 'Sample width', 'Sample rate', 'Number of frames', 'Compression type', 'Compression name')

    # Audio effect processing is intrinsically imprecise, so we need to always allow tolerance.
    _tolerance = 1

    def __init__(self, in1, in2):
        if isinstance(in1, str):
            waveFile1 = wave.open(StringIO(in1), 'r')
        else:
            waveFile1 = wave.open(BytesIO(in1), 'rb')
        if isinstance(in2, str):
            waveFile2 = wave.open(StringIO(in2), 'r')
        else:
            waveFile2 = wave.open(BytesIO(in2), 'rb')

        params1 = waveFile1.getparams()
        params2 = waveFile2.getparams()

        self._diff = []

        self._filesAreIdentical = not sum(map(self._diffParam, params1, params2, self._paramNames))
        self._filesAreIdenticalWithinTolerance = self._filesAreIdentical

        if not self._filesAreIdentical:
            return

        # Metadata is identical, compare the content now.

        channelCount1 = waveFile1.getnchannels()
        frameCount1 = waveFile1.getnframes()
        sampleWidth1 = waveFile1.getsampwidth()
        channelCount2 = waveFile2.getnchannels()
        frameCount2 = waveFile2.getnframes()
        sampleWidth2 = waveFile2.getsampwidth()

        allData1 = self._readSamples(waveFile1, sampleWidth1, frameCount1 * channelCount1)
        allData2 = self._readSamples(waveFile2, sampleWidth2, frameCount2 * channelCount2)
        results = list(map(self._diffSample, allData1, allData2, range(max(frameCount1 * channelCount1, frameCount2 * channelCount2))))

        cumulativeSampleDiff = sum(results)
        differingSampleCount = len(list(filter(bool, results)))
        self._filesAreIdentical = not differingSampleCount
        self._filesAreIdenticalWithinTolerance = not len(list(filter(lambda x: x > self._tolerance, results)))

        if differingSampleCount:
            self._diff.append('')
            self._diff.append('Total differing samples: %d' % differingSampleCount)
            self._diff.append('Percentage of differing samples: %0.3f%%' % (100 * float(differingSampleCount) / max(frameCount1, frameCount2)))
            self._diff.append('Cumulative sample difference: %d' % cumulativeSampleDiff)
            self._diff.append('Average sample difference: %f' % (float(cumulativeSampleDiff) / differingSampleCount))

    def _diffParam(self, param1, param2, paramName):
        if param1 == param2:
            return False
        self._diff.append(paramName)
        self._diff.append('< %s' % str(param1))
        self._diff.append('---')
        self._diff.append('> %s' % str(param2))
        return True

    @staticmethod
    def _readSamples(file, sampleWidth, nSamples):
        allFrames = file.readframes(nSamples)
        unpackFormat = 'b' if sampleWidth == 1 else 'h'
        return struct.unpack('<%d%s' % (nSamples, unpackFormat), allFrames)

    def _diffSample(self, data1, data2, i):
        if (data1 != data2):
            self._diff.append('Sample #%d' % i)
            self._diff.append('< %d' % data1)
            self._diff.append('---')
            self._diff.append('> %d' % data2)
        return abs(data1 - data2)

    def filesAreIdentical(self):
        return self._filesAreIdentical

    def filesAreIdenticalWithinTolerance(self):
        return self._filesAreIdenticalWithinTolerance

    def diffText(self):
        return '\n'.join(self._diff)
