# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.

"""Echo path simulation module.
"""

import hashlib
import os

from . import signal_processing


class EchoPathSimulator(object):
  """Abstract class for the echo path simulators.

  In general, an echo path simulator is a function of the render signal and
  simulates the propagation of the latter into the microphone (e.g., due to
  mechanical or electrical paths).
  """

  NAME = None
  REGISTERED_CLASSES = {}

  def __init__(self):
    pass

  def Simulate(self, output_path):
    """Creates the echo signal and stores it in an audio file (abstract method).

    Args:
      output_path: Path in which any output can be saved.

    Returns:
      Path to the generated audio track file or None if no echo is present.
    """
    raise NotImplementedError()

  @classmethod
  def RegisterClass(cls, class_to_register):
    """Registers an EchoPathSimulator implementation.

    Decorator to automatically register the classes that extend
    EchoPathSimulator.
    Example usage:

    @EchoPathSimulator.RegisterClass
    class NoEchoPathSimulator(EchoPathSimulator):
      pass
    """
    cls.REGISTERED_CLASSES[class_to_register.NAME] = class_to_register
    return class_to_register


@EchoPathSimulator.RegisterClass
class NoEchoPathSimulator(EchoPathSimulator):
  """Simulates absence of echo."""

  NAME = 'noecho'

  def __init__(self):
    EchoPathSimulator.__init__(self)

  def Simulate(self, output_path):
    return None


@EchoPathSimulator.RegisterClass
class LinearEchoPathSimulator(EchoPathSimulator):
  """Simulates linear echo path.

  This class applies a given impulse response to the render input and then it
  sums the signal to the capture input signal.
  """

  NAME = 'linear'

  def __init__(self, render_input_filepath, impulse_response):
    """
    Args:
      render_input_filepath: Render audio track file.
      impulse_response: list or numpy vector of float values.
    """
    EchoPathSimulator.__init__(self)
    self._render_input_filepath = render_input_filepath
    self._impulse_response = impulse_response

  def Simulate(self, output_path):
    """Simulates linear echo path."""
    # Form the file name with a hash of the impulse response.
    impulse_response_hash = hashlib.sha256(
        str(self._impulse_response).encode('utf-8', 'ignore')).hexdigest()
    echo_filepath = os.path.join(output_path, 'linear_echo_{}.wav'.format(
        impulse_response_hash))

    # If the simulated echo audio track file does not exists, create it.
    if not os.path.exists(echo_filepath):
      render = signal_processing.SignalProcessingUtils.LoadWav(
          self._render_input_filepath)
      echo = signal_processing.SignalProcessingUtils.ApplyImpulseResponse(
          render, self._impulse_response)
      signal_processing.SignalProcessingUtils.SaveWav(echo_filepath, echo)

    return echo_filepath


@EchoPathSimulator.RegisterClass
class RecordedEchoPathSimulator(EchoPathSimulator):
  """Uses recorded echo.

  This class uses the clean capture input file name to build the file name of
  the corresponding recording containing echo (a predefined suffix is used).
  Such a file is expected to be already existing.
  """

  NAME = 'recorded'

  _FILE_NAME_SUFFIX = '_echo'

  def __init__(self, render_input_filepath):
    EchoPathSimulator.__init__(self)
    self._render_input_filepath = render_input_filepath

  def Simulate(self, output_path):
    """Uses recorded echo path."""
    path, file_name_ext = os.path.split(self._render_input_filepath)
    file_name, file_ext = os.path.splitext(file_name_ext)
    echo_filepath = os.path.join(path, '{}{}{}'.format(
        file_name, self._FILE_NAME_SUFFIX, file_ext))
    assert os.path.exists(echo_filepath), (
           'cannot find the echo audio track file {}'.format(echo_filepath))
    return echo_filepath
