// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/media/audio/lib/effects_loader/effects_processor.h"

#include <gtest/gtest.h>

#include "src/lib/fxl/logging.h"
#include "src/media/audio/effects/test_effects/test_effects.h"
#include "src/media/audio/lib/effects_loader/effects_loader_test_base.h"

namespace media::audio {
namespace {

class EffectsProcessorTest : public test::EffectsLoaderTestBase {};

// The following tests validates the EffectsProcessor class itself.
//
// Verify the creation, uniqueness, quantity and deletion of effect instances.
TEST_F(EffectsProcessorTest, CreateDelete) {
  ASSERT_EQ(ZX_OK, test_effects()->add_effect({{"assign_to_1.0", FUCHSIA_AUDIO_EFFECTS_CHANNELS_ANY,
                                                FUCHSIA_AUDIO_EFFECTS_CHANNELS_SAME_AS_IN},
                                               TEST_EFFECTS_ACTION_ASSIGN,
                                               1.0}));

  Effect effect3 = effects_loader()->CreateEffect(0, 1, 1, 1, {});
  Effect effect1 = effects_loader()->CreateEffect(0, 1, 1, 1, {});
  Effect effect2 = effects_loader()->CreateEffect(0, 1, 1, 1, {});
  Effect effect4 = effects_loader()->CreateEffect(0, 1, 1, 1, {});

  ASSERT_TRUE(effect1);
  ASSERT_TRUE(effect2);
  ASSERT_TRUE(effect3);
  ASSERT_TRUE(effect4);

  EXPECT_TRUE(effect1.get() != effect2.get() && effect1.get() != effect3.get() &&
              effect1.get() != effect4.get() && effect2.get() != effect3.get() &&
              effect2.get() != effect4.get() && effect3.get() != effect4.get());

  fuchsia_audio_effects_handle_t effects_handle1 = effect1.get();
  fuchsia_audio_effects_handle_t effects_handle2 = effect2.get();
  fuchsia_audio_effects_handle_t effects_handle3 = effect3.get();
  fuchsia_audio_effects_handle_t effects_handle4 = effect4.get();

  // Create processor
  {
    EffectsProcessor processor;
    processor.AddEffect(std::move(effect3));
    processor.AddEffect(std::move(effect1));
    processor.AddEffect(std::move(effect2));
    processor.AddEffect(std::move(effect4));
    EXPECT_EQ(processor.size(), 4);

    EXPECT_EQ(effects_handle3, processor.GetEffectAt(0).get());
    EXPECT_EQ(effects_handle1, processor.GetEffectAt(1).get());
    EXPECT_EQ(effects_handle2, processor.GetEffectAt(2).get());
    EXPECT_EQ(effects_handle4, processor.GetEffectAt(3).get());

    EXPECT_EQ(4u, test_effects()->num_instances());
  }

  // All instances should be deleted when the processor is destructed.
  EXPECT_EQ(0u, test_effects()->num_instances());
  test_effects()->clear_effects();
}

// Verify (at a VERY Basic level) the methods that handle data flow.
TEST_F(EffectsProcessorTest, ProcessInPlaceFlush) {
  ASSERT_EQ(ZX_OK,
            test_effects()->add_effect({{"increment_by_1.0", FUCHSIA_AUDIO_EFFECTS_CHANNELS_ANY,
                                         FUCHSIA_AUDIO_EFFECTS_CHANNELS_SAME_AS_IN},
                                        TEST_EFFECTS_ACTION_ADD,
                                        1.0}));
  ASSERT_EQ(ZX_OK,
            test_effects()->add_effect({{"increment_by_2.0", FUCHSIA_AUDIO_EFFECTS_CHANNELS_ANY,
                                         FUCHSIA_AUDIO_EFFECTS_CHANNELS_SAME_AS_IN},
                                        TEST_EFFECTS_ACTION_ADD,
                                        2.0}));
  ASSERT_EQ(ZX_OK,
            test_effects()->add_effect({{"assign_to_12.0", FUCHSIA_AUDIO_EFFECTS_CHANNELS_ANY,
                                         FUCHSIA_AUDIO_EFFECTS_CHANNELS_SAME_AS_IN},
                                        TEST_EFFECTS_ACTION_ASSIGN,
                                        12.0}));
  ASSERT_EQ(ZX_OK,
            test_effects()->add_effect({{"increment_by_4.0", FUCHSIA_AUDIO_EFFECTS_CHANNELS_ANY,
                                         FUCHSIA_AUDIO_EFFECTS_CHANNELS_SAME_AS_IN},
                                        TEST_EFFECTS_ACTION_ADD,
                                        4.0}));

  float buff[4] = {0, 1.0, 2.0, 3.0};

  // Before instances added, ProcessInPlace and Flush should succeed.
  EffectsProcessor processor;
  EXPECT_EQ(processor.ProcessInPlace(4, buff), ZX_OK);
  EXPECT_EQ(processor.Flush(), ZX_OK);
  EXPECT_EQ(0.0, buff[0]);
  EXPECT_EQ(1.0, buff[1]);
  EXPECT_EQ(2.0, buff[2]);
  EXPECT_EQ(3.0, buff[3]);

  // Chaining four instances together, ProcessInPlace and flush should succeed.
  Effect effect1 = effects_loader()->CreateEffect(0, 1, 1, 1, {});
  Effect effect2 = effects_loader()->CreateEffect(1, 1, 1, 1, {});
  Effect effect3 = effects_loader()->CreateEffect(2, 1, 1, 1, {});
  Effect effect4 = effects_loader()->CreateEffect(3, 1, 1, 1, {});
  ASSERT_TRUE(effect1 && effect2 && effect3 && effect4);

  processor.AddEffect(std::move(effect1));
  processor.AddEffect(std::move(effect2));
  processor.AddEffect(std::move(effect3));
  processor.AddEffect(std::move(effect4));
  EXPECT_EQ(4u, test_effects()->num_instances());

  // The first 2 processors will mutate data, but this will be clobbered by the 3rd processor which
  // just sets every sample to 12.0. The final processor will increment by 4.0 resulting in the
  // expected 16.0 values.
  EXPECT_EQ(processor.ProcessInPlace(4, buff), ZX_OK);
  EXPECT_EQ(buff[0], 16.0);
  EXPECT_EQ(buff[1], 16.0);
  EXPECT_EQ(buff[2], 16.0);
  EXPECT_EQ(buff[3], 16.0);

  // All effects should have initial flush count 0.
  test_effects_inspect_state inspect1 = {};
  test_effects_inspect_state inspect2 = {};
  test_effects_inspect_state inspect3 = {};
  test_effects_inspect_state inspect4 = {};
  EXPECT_EQ(ZX_OK, test_effects()->inspect_instance(processor.GetEffectAt(0).get(), &inspect1));
  EXPECT_EQ(ZX_OK, test_effects()->inspect_instance(processor.GetEffectAt(1).get(), &inspect2));
  EXPECT_EQ(ZX_OK, test_effects()->inspect_instance(processor.GetEffectAt(2).get(), &inspect3));
  EXPECT_EQ(ZX_OK, test_effects()->inspect_instance(processor.GetEffectAt(3).get(), &inspect4));
  EXPECT_EQ(0u, inspect1.flush_count);
  EXPECT_EQ(0u, inspect2.flush_count);
  EXPECT_EQ(0u, inspect3.flush_count);
  EXPECT_EQ(0u, inspect4.flush_count);

  // Flush, just sanity test the test_effects library has observed the flush call on each effect.
  EXPECT_EQ(processor.Flush(), ZX_OK);
  EXPECT_EQ(ZX_OK, test_effects()->inspect_instance(processor.GetEffectAt(0).get(), &inspect1));
  EXPECT_EQ(ZX_OK, test_effects()->inspect_instance(processor.GetEffectAt(1).get(), &inspect2));
  EXPECT_EQ(ZX_OK, test_effects()->inspect_instance(processor.GetEffectAt(2).get(), &inspect3));
  EXPECT_EQ(ZX_OK, test_effects()->inspect_instance(processor.GetEffectAt(3).get(), &inspect4));
  EXPECT_EQ(1u, inspect1.flush_count);
  EXPECT_EQ(1u, inspect2.flush_count);
  EXPECT_EQ(1u, inspect3.flush_count);
  EXPECT_EQ(1u, inspect4.flush_count);

  // Zero num_frames is valid and should succeed. We assign the buff to some random values here
  // to ensure the processor does not clobber them.
  buff[0] = 20.0;
  buff[1] = 21.0;
  buff[2] = 22.0;
  buff[3] = 23.0;
  EXPECT_EQ(processor.ProcessInPlace(0, buff), ZX_OK);
  EXPECT_EQ(buff[0], 20.0);
  EXPECT_EQ(buff[1], 21.0);
  EXPECT_EQ(buff[2], 22.0);
  EXPECT_EQ(buff[3], 23.0);

  // If no buffer provided, ProcessInPlace should fail (even if 0 num_frames).
  EXPECT_NE(processor.ProcessInPlace(0, nullptr), ZX_OK);
}

}  // namespace
}  // namespace media::audio
