# 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 sys
import tempfile
import wave

from io import BytesIO


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, file):
            waveFile1 = wave.open(in1, 'rb')
        else:
            waveFile1 = wave.open(BytesIO(in1), 'rb')
        if isinstance(in2, file):
            waveFile1 = wave.open(in2, 'rb')
        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 = map(self._diffSample, allData1, allData2, xrange(max(frameCount1 * channelCount1, frameCount2 * channelCount2)))

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

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

    def _diffParam(self, param1, param2, paramName):
        if param1 == param2:
            return False
        self._diff += paramName + '\n'
        self._diff += '< %s\n' % str(param1)
        self._diff += '---\n'
        self._diff += '> %s\n' % 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 += 'Sample #%d\n' % i
            self._diff += '< %d\n' % data1
            self._diff += '---\n'
            self._diff += '> %d\n' % data2
        return abs(data1 - data2)

    def filesAreIdentical(self):
        return self._filesAreIdentical

    def filesAreIdenticalWithinTolerance(self):
        return self._filesAreIdenticalWithinTolerance

    def diffText(self):
        return self._diff
