// Copyright 2022 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/format2/channel_mapper.h"

#include <cstdint>
#include <vector>

#include <gtest/gtest.h>

#include "src/media/audio/lib/format2/sample_converter.h"

namespace media_audio {
namespace {

TEST(ChannelMapperTest, SameChannels) {
  ChannelMapper<int16_t, 4, 4> mapper;

  const std::vector<int16_t> input = {-0x4000, kMinInt16, 0, 0x4000};
  const std::vector<float> expected = {-0.5f, -1.0f, 0.0f, 0.5f};
  for (size_t channel = 0; channel < expected.size(); ++channel) {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
  }
}

TEST(ChannelMapperTest, MonoToStereo) {
  ChannelMapper<int16_t, 1, 2> mapper;

  const int16_t input = 0x4000;  // 0.5f
  for (size_t channel = 0; channel < 2; ++channel) {
    EXPECT_FLOAT_EQ(mapper.Map(&input, 0), 0.5f);
  }
}

TEST(ChannelMapperTest, MonoToThreeChannels) {
  ChannelMapper<uint8_t, 1, 3> mapper;

  const uint8_t input = 0x40;  // -0.5f
  for (size_t channel = 0; channel < 3; ++channel) {
    EXPECT_FLOAT_EQ(mapper.Map(&input, 0), -0.5f);
  }
}

TEST(ChannelMapperTest, MonoToFourChannels) {
  ChannelMapper<float, 1, 4> mapper;

  const float input = 0.2f;
  for (size_t channel = 0; channel < 4; ++channel) {
    EXPECT_FLOAT_EQ(mapper.Map(&input, 0), 0.2f);
  }
}

TEST(ChannelMapperTest, StereoToMono) {
  ChannelMapper<int16_t, 2, 1> mapper;

  const std::vector<int16_t> input = {-0x2000, -0x4000};  // {-0.25f, -0.5f}
  EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), -0.375f);
}

TEST(ChannelMapperTest, StereoToThreeChannels) {
  ChannelMapper<float, 2, 3> mapper;

  const std::vector<float> input = {-0.25f, 0.75f};
  const std::vector<float> expected = {-0.25f, 0.75f, 0.25f};
  for (size_t channel = 0; channel < expected.size(); ++channel) {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
  }
}

TEST(ChannelMapperTest, StereoToFourChannels) {
  ChannelMapper<float, 2, 4> mapper;

  const std::vector<float> input = {-0.25f, 0.75f};
  const std::vector<float> expected = {-0.25f, 0.75f, -0.25f, 0.75f};
  for (size_t channel = 0; channel < expected.size(); ++channel) {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
  }
}

TEST(ChannelMapperTest, ThreeChannelsToMono) {
  ChannelMapper<float, 3, 1> mapper;

  const std::vector<float> input = {-1.0f, 0.5f, -0.1f};
  EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), -0.2f);
}

TEST(ChannelMapperTest, ThreeChannelsToStereo) {
  ChannelMapper<float, 3, 2> mapper;

  const std::vector<float> input = {1.0f, -0.5f, -0.5f};
  const std::vector<float> expected = {0.378679656f, -0.5f};
  for (size_t channel = 0; channel < expected.size(); ++channel) {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
  }
}

TEST(ChannelMapperTest, FourChannelsToMono) {
  ChannelMapper<float, 4, 1> mapper;

  const std::vector<float> input = {1.0f, 2.0f, 3.0f, 4.0f};
  if constexpr (kEnable4ChannelWorkaround) {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), 1.5f);
  } else {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), 5.0f);
  }
}

TEST(ChannelMapperTest, FourChannelsToStereo) {
  ChannelMapper<float, 4, 2> mapper;

  const std::vector<float> input = {1.0f, 2.0f, 3.0f, 4.0f};
  if constexpr (kEnable4ChannelWorkaround) {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), 1.0f);
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), 1), 2.0f);
  } else {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), 1.5f);
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), 1), 3.0f);
  }
}

TEST(ChannelMapperTest, CustomizableSameChannels) {
  ChannelMapper<float, 2, 2, /*Customizable=*/true> mapper({{
      {-1.0f, 0.0f},
      {0.5f, 0.5f},
  }});

  const std::vector<float> input = {2.0f, 3.0f};
  const std::vector<float> expected = {-2.0f, 2.5f};
  for (size_t channel = 0; channel < expected.size(); ++channel) {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
  }
}

TEST(ChannelMapperTest, CustomizableSingleToMulti) {
  ChannelMapper<float, 1, 3, /*Customizable=*/true> mapper({{{1.0f}, {-2.0f}, {3.0f}}});

  const std::vector<float> input = {0.5f};
  const std::vector<float> expected = {0.5f, -1.0f, 1.5f};
  for (size_t channel = 0; channel < expected.size(); ++channel) {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
  }
}

TEST(ChannelMapperTest, CustomizableMultiToSingle) {
  ChannelMapper<float, 2, 1, /*Customizable=*/true> mapper({{{1.0f, 0.25f}}});

  const std::vector<float> input = {2.0f, 4.0f};
  EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), 3.0f);
}

TEST(ChannelMapperTest, CustomizableMultiToMulti) {
  ChannelMapper<float, 3, 5, /*Customizable=*/true> mapper({{
      {1.0f, 0.0f, 0.0f},
      {0.0f, 1.0f, 0.0f},
      {0.0f, 0.0f, 1.0f},
      {1.0f, 1.0f, 1.0f},
      {-1.0f, 2.0f, -3.0f},
  }});

  const std::vector<float> input = {1.0f, 2.0f, 3.0f};
  const std::vector<float> expected = {1.0f, 2.0f, 3.0f, 6.0f, -6.0f};
  for (size_t channel = 0; channel < expected.size(); ++channel) {
    EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
  }
}

}  // namespace
}  // namespace media_audio
