# 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.
"""APM module simulator.
"""

import logging
import os

from . import annotations
from . import data_access
from . import echo_path_simulation
from . import echo_path_simulation_factory
from . import eval_scores
from . import exceptions
from . import input_mixer
from . import input_signal_creator
from . import signal_processing
from . import test_data_generation


class ApmModuleSimulator(object):
    """Audio processing module (APM) simulator class.
  """

    _TEST_DATA_GENERATOR_CLASSES = (
        test_data_generation.TestDataGenerator.REGISTERED_CLASSES)
    _EVAL_SCORE_WORKER_CLASSES = eval_scores.EvaluationScore.REGISTERED_CLASSES

    _PREFIX_APM_CONFIG = 'apmcfg-'
    _PREFIX_CAPTURE = 'capture-'
    _PREFIX_RENDER = 'render-'
    _PREFIX_ECHO_SIMULATOR = 'echosim-'
    _PREFIX_TEST_DATA_GEN = 'datagen-'
    _PREFIX_TEST_DATA_GEN_PARAMS = 'datagen_params-'
    _PREFIX_SCORE = 'score-'

    def __init__(self,
                 test_data_generator_factory,
                 evaluation_score_factory,
                 ap_wrapper,
                 evaluator,
                 external_vads=None):
        if external_vads is None:
            external_vads = {}
        self._test_data_generator_factory = test_data_generator_factory
        self._evaluation_score_factory = evaluation_score_factory
        self._audioproc_wrapper = ap_wrapper
        self._evaluator = evaluator
        self._annotator = annotations.AudioAnnotationsExtractor(
            annotations.AudioAnnotationsExtractor.VadType.ENERGY_THRESHOLD
            | annotations.AudioAnnotationsExtractor.VadType.WEBRTC_COMMON_AUDIO
            | annotations.AudioAnnotationsExtractor.VadType.WEBRTC_APM,
            external_vads)

        # Init.
        self._test_data_generator_factory.SetOutputDirectoryPrefix(
            self._PREFIX_TEST_DATA_GEN_PARAMS)
        self._evaluation_score_factory.SetScoreFilenamePrefix(
            self._PREFIX_SCORE)

        # Properties for each run.
        self._base_output_path = None
        self._output_cache_path = None
        self._test_data_generators = None
        self._evaluation_score_workers = None
        self._config_filepaths = None
        self._capture_input_filepaths = None
        self._render_input_filepaths = None
        self._echo_path_simulator_class = None

    @classmethod
    def GetPrefixApmConfig(cls):
        return cls._PREFIX_APM_CONFIG

    @classmethod
    def GetPrefixCapture(cls):
        return cls._PREFIX_CAPTURE

    @classmethod
    def GetPrefixRender(cls):
        return cls._PREFIX_RENDER

    @classmethod
    def GetPrefixEchoSimulator(cls):
        return cls._PREFIX_ECHO_SIMULATOR

    @classmethod
    def GetPrefixTestDataGenerator(cls):
        return cls._PREFIX_TEST_DATA_GEN

    @classmethod
    def GetPrefixTestDataGeneratorParameters(cls):
        return cls._PREFIX_TEST_DATA_GEN_PARAMS

    @classmethod
    def GetPrefixScore(cls):
        return cls._PREFIX_SCORE

    def Run(self,
            config_filepaths,
            capture_input_filepaths,
            test_data_generator_names,
            eval_score_names,
            output_dir,
            render_input_filepaths=None,
            echo_path_simulator_name=(
                echo_path_simulation.NoEchoPathSimulator.NAME)):
        """Runs the APM simulation.

    Initializes paths and required instances, then runs all the simulations.
    The render input can be optionally added. If added, the number of capture
    input audio tracks and the number of render input audio tracks have to be
    equal. The two lists are used to form pairs of capture and render input.

    Args:
      config_filepaths: set of APM configuration files to test.
      capture_input_filepaths: set of capture input audio track files to test.
      test_data_generator_names: set of test data generator names to test.
      eval_score_names: set of evaluation score names to test.
      output_dir: base path to the output directory for wav files and outcomes.
      render_input_filepaths: set of render input audio track files to test.
      echo_path_simulator_name: name of the echo path simulator to use when
                                render input is provided.
    """
        assert render_input_filepaths is None or (
            len(capture_input_filepaths) == len(render_input_filepaths)), (
                'render input set size not matching input set size')
        assert render_input_filepaths is None or echo_path_simulator_name in (
            echo_path_simulation.EchoPathSimulator.REGISTERED_CLASSES), (
                'invalid echo path simulator')
        self._base_output_path = os.path.abspath(output_dir)

        # Output path used to cache the data shared across simulations.
        self._output_cache_path = os.path.join(self._base_output_path,
                                               '_cache')

        # Instance test data generators.
        self._test_data_generators = [
            self._test_data_generator_factory.GetInstance(
                test_data_generators_class=(
                    self._TEST_DATA_GENERATOR_CLASSES[name]))
            for name in (test_data_generator_names)
        ]

        # Instance evaluation score workers.
        self._evaluation_score_workers = [
            self._evaluation_score_factory.GetInstance(
                evaluation_score_class=self._EVAL_SCORE_WORKER_CLASSES[name])
            for (name) in eval_score_names
        ]

        # Set APM configuration file paths.
        self._config_filepaths = self._CreatePathsCollection(config_filepaths)

        # Set probing signal file paths.
        if render_input_filepaths is None:
            # Capture input only.
            self._capture_input_filepaths = self._CreatePathsCollection(
                capture_input_filepaths)
            self._render_input_filepaths = None
        else:
            # Set both capture and render input signals.
            self._SetTestInputSignalFilePaths(capture_input_filepaths,
                                              render_input_filepaths)

        # Set the echo path simulator class.
        self._echo_path_simulator_class = (
            echo_path_simulation.EchoPathSimulator.
            REGISTERED_CLASSES[echo_path_simulator_name])

        self._SimulateAll()

    def _SimulateAll(self):
        """Runs all the simulations.

    Iterates over the combinations of APM configurations, probing signals, and
    test data generators. This method is mainly responsible for the creation of
    the cache and output directories required in order to call _Simulate().
    """
        without_render_input = self._render_input_filepaths is None

        # Try different APM config files.
        for config_name in self._config_filepaths:
            config_filepath = self._config_filepaths[config_name]

            # Try different capture-render pairs.
            for capture_input_name in self._capture_input_filepaths:
                # Output path for the capture signal annotations.
                capture_annotations_cache_path = os.path.join(
                    self._output_cache_path,
                    self._PREFIX_CAPTURE + capture_input_name)
                data_access.MakeDirectory(capture_annotations_cache_path)

                # Capture.
                capture_input_filepath = self._capture_input_filepaths[
                    capture_input_name]
                if not os.path.exists(capture_input_filepath):
                    # If the input signal file does not exist, try to create using the
                    # available input signal creators.
                    self._CreateInputSignal(capture_input_filepath)
                assert os.path.exists(capture_input_filepath)
                self._ExtractCaptureAnnotations(
                    capture_input_filepath, capture_annotations_cache_path)

                # Render and simulated echo path (optional).
                render_input_filepath = None if without_render_input else (
                    self._render_input_filepaths[capture_input_name])
                render_input_name = '(none)' if without_render_input else (
                    self._ExtractFileName(render_input_filepath))
                echo_path_simulator = (echo_path_simulation_factory.
                                       EchoPathSimulatorFactory.GetInstance(
                                           self._echo_path_simulator_class,
                                           render_input_filepath))

                # Try different test data generators.
                for test_data_generators in self._test_data_generators:
                    logging.info(
                        'APM config preset: <%s>, capture: <%s>, render: <%s>,'
                        'test data generator: <%s>,  echo simulator: <%s>',
                        config_name, capture_input_name, render_input_name,
                        test_data_generators.NAME, echo_path_simulator.NAME)

                    # Output path for the generated test data.
                    test_data_cache_path = os.path.join(
                        capture_annotations_cache_path,
                        self._PREFIX_TEST_DATA_GEN + test_data_generators.NAME)
                    data_access.MakeDirectory(test_data_cache_path)
                    logging.debug('test data cache path: <%s>',
                                  test_data_cache_path)

                    # Output path for the echo simulator and APM input mixer output.
                    echo_test_data_cache_path = os.path.join(
                        test_data_cache_path,
                        'echosim-{}'.format(echo_path_simulator.NAME))
                    data_access.MakeDirectory(echo_test_data_cache_path)
                    logging.debug('echo test data cache path: <%s>',
                                  echo_test_data_cache_path)

                    # Full output path.
                    output_path = os.path.join(
                        self._base_output_path,
                        self._PREFIX_APM_CONFIG + config_name,
                        self._PREFIX_CAPTURE + capture_input_name,
                        self._PREFIX_RENDER + render_input_name,
                        self._PREFIX_ECHO_SIMULATOR + echo_path_simulator.NAME,
                        self._PREFIX_TEST_DATA_GEN + test_data_generators.NAME)
                    data_access.MakeDirectory(output_path)
                    logging.debug('output path: <%s>', output_path)

                    self._Simulate(test_data_generators,
                                   capture_input_filepath,
                                   render_input_filepath, test_data_cache_path,
                                   echo_test_data_cache_path, output_path,
                                   config_filepath, echo_path_simulator)

    @staticmethod
    def _CreateInputSignal(input_signal_filepath):
        """Creates a missing input signal file.

    The file name is parsed to extract input signal creator and params. If a
    creator is matched and the parameters are valid, a new signal is generated
    and written in `input_signal_filepath`.

    Args:
      input_signal_filepath: Path to the input signal audio file to write.

    Raises:
      InputSignalCreatorException
    """
        filename = os.path.splitext(
            os.path.split(input_signal_filepath)[-1])[0]
        filename_parts = filename.split('-')

        if len(filename_parts) < 2:
            raise exceptions.InputSignalCreatorException(
                'Cannot parse input signal file name')

        signal, metadata = input_signal_creator.InputSignalCreator.Create(
            filename_parts[0], filename_parts[1].split('_'))

        signal_processing.SignalProcessingUtils.SaveWav(
            input_signal_filepath, signal)
        data_access.Metadata.SaveFileMetadata(input_signal_filepath, metadata)

    def _ExtractCaptureAnnotations(self,
                                   input_filepath,
                                   output_path,
                                   annotation_name=""):
        self._annotator.Extract(input_filepath)
        self._annotator.Save(output_path, annotation_name)

    def _Simulate(self, test_data_generators, clean_capture_input_filepath,
                  render_input_filepath, test_data_cache_path,
                  echo_test_data_cache_path, output_path, config_filepath,
                  echo_path_simulator):
        """Runs a single set of simulation.

    Simulates a given combination of APM configuration, probing signal, and
    test data generator. It iterates over the test data generator
    internal configurations.

    Args:
      test_data_generators: TestDataGenerator instance.
      clean_capture_input_filepath: capture input audio track file to be
                                    processed by a test data generator and
                                    not affected by echo.
      render_input_filepath: render input audio track file to test.
      test_data_cache_path: path for the generated test audio track files.
      echo_test_data_cache_path: path for the echo simulator.
      output_path: base output path for the test data generator.
      config_filepath: APM configuration file to test.
      echo_path_simulator: EchoPathSimulator instance.
    """
        # Generate pairs of noisy input and reference signal files.
        test_data_generators.Generate(
            input_signal_filepath=clean_capture_input_filepath,
            test_data_cache_path=test_data_cache_path,
            base_output_path=output_path)

        # Extract metadata linked to the clean input file (if any).
        apm_input_metadata = None
        try:
            apm_input_metadata = data_access.Metadata.LoadFileMetadata(
                clean_capture_input_filepath)
        except IOError as e:
            apm_input_metadata = {}
        apm_input_metadata['test_data_gen_name'] = test_data_generators.NAME
        apm_input_metadata['test_data_gen_config'] = None

        # For each test data pair, simulate a call and evaluate.
        for config_name in test_data_generators.config_names:
            logging.info(' - test data generator config: <%s>', config_name)
            apm_input_metadata['test_data_gen_config'] = config_name

            # Paths to the test data generator output.
            # Note that the reference signal does not depend on the render input
            # which is optional.
            noisy_capture_input_filepath = (
                test_data_generators.noisy_signal_filepaths[config_name])
            reference_signal_filepath = (
                test_data_generators.reference_signal_filepaths[config_name])

            # Output path for the evaluation (e.g., APM output file).
            evaluation_output_path = test_data_generators.apm_output_paths[
                config_name]

            # Paths to the APM input signals.
            echo_path_filepath = echo_path_simulator.Simulate(
                echo_test_data_cache_path)
            apm_input_filepath = input_mixer.ApmInputMixer.Mix(
                echo_test_data_cache_path, noisy_capture_input_filepath,
                echo_path_filepath)

            # Extract annotations for the APM input mix.
            apm_input_basepath, apm_input_filename = os.path.split(
                apm_input_filepath)
            self._ExtractCaptureAnnotations(
                apm_input_filepath, apm_input_basepath,
                os.path.splitext(apm_input_filename)[0] + '-')

            # Simulate a call using APM.
            self._audioproc_wrapper.Run(
                config_filepath=config_filepath,
                capture_input_filepath=apm_input_filepath,
                render_input_filepath=render_input_filepath,
                output_path=evaluation_output_path)

            try:
                # Evaluate.
                self._evaluator.Run(
                    evaluation_score_workers=self._evaluation_score_workers,
                    apm_input_metadata=apm_input_metadata,
                    apm_output_filepath=self._audioproc_wrapper.
                    output_filepath,
                    reference_input_filepath=reference_signal_filepath,
                    render_input_filepath=render_input_filepath,
                    output_path=evaluation_output_path,
                )

                # Save simulation metadata.
                data_access.Metadata.SaveAudioTestDataPaths(
                    output_path=evaluation_output_path,
                    clean_capture_input_filepath=clean_capture_input_filepath,
                    echo_free_capture_filepath=noisy_capture_input_filepath,
                    echo_filepath=echo_path_filepath,
                    render_filepath=render_input_filepath,
                    capture_filepath=apm_input_filepath,
                    apm_output_filepath=self._audioproc_wrapper.
                    output_filepath,
                    apm_reference_filepath=reference_signal_filepath,
                    apm_config_filepath=config_filepath,
                )
            except exceptions.EvaluationScoreException as e:
                logging.warning('the evaluation failed: %s', e.message)
                continue

    def _SetTestInputSignalFilePaths(self, capture_input_filepaths,
                                     render_input_filepaths):
        """Sets input and render input file paths collections.

    Pairs the input and render input files by storing the file paths into two
    collections. The key is the file name of the input file.

    Args:
      capture_input_filepaths: list of file paths.
      render_input_filepaths: list of file paths.
    """
        self._capture_input_filepaths = {}
        self._render_input_filepaths = {}
        assert len(capture_input_filepaths) == len(render_input_filepaths)
        for capture_input_filepath, render_input_filepath in zip(
                capture_input_filepaths, render_input_filepaths):
            name = self._ExtractFileName(capture_input_filepath)
            self._capture_input_filepaths[name] = os.path.abspath(
                capture_input_filepath)
            self._render_input_filepaths[name] = os.path.abspath(
                render_input_filepath)

    @classmethod
    def _CreatePathsCollection(cls, filepaths):
        """Creates a collection of file paths.

    Given a list of file paths, makes a collection with one item for each file
    path. The value is absolute path, the key is the file name without
    extenstion.

    Args:
      filepaths: list of file paths.

    Returns:
      A dict.
    """
        filepaths_collection = {}
        for filepath in filepaths:
            name = cls._ExtractFileName(filepath)
            filepaths_collection[name] = os.path.abspath(filepath)
        return filepaths_collection

    @classmethod
    def _ExtractFileName(cls, filepath):
        return os.path.splitext(os.path.split(filepath)[-1])[0]
