# 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 webkitpy.common.unicode_compatibility 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 += '\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
