// Copyright 2015 The Chromium 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 "media/cast/common/expanded_value_base.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace media {
namespace cast {

namespace {

// A basic subclass of ExpandedValueBase to use for testing.
class TestValue : public ExpandedValueBase<int64_t, TestValue> {
 public:
  explicit TestValue(int64_t value) : ExpandedValueBase(value) {}
};

}  // namespace

// Tests the various scenarios of truncating and then re-expanding values, and
// confirming the correct behavior.  Note that, while the code below just tests
// truncation/expansion to/from 8 bits, the 16- and 32-bit cases are implicitly
// confirmed because the Expand() method uses the compiler to derive all of its
// constants (based on the type of its argument).
TEST(ExpandedValueBaseTest, TruncationAndExpansion) {
  // Test that expansion works when the reference is always equal to the value
  // that was truncated.
  for (int64_t i = -512; i <= 512; ++i) {
    const TestValue original_value(i);
    const uint8_t truncated = original_value.lower_8_bits();
    const TestValue reference(i);
    ASSERT_EQ(original_value, reference.Expand(truncated)) << "i=" << i;
  }

  // Test that expansion works when the reference is always one less than the
  // value that was truncated.
  for (int64_t i = -512; i <= 512; ++i) {
    const TestValue original_value(i);
    const uint8_t truncated = original_value.lower_8_bits();
    const TestValue reference(i - 1);
    ASSERT_EQ(original_value, reference.Expand(truncated)) << "i=" << i;
  }

  // Test that expansion works when the reference is always one greater than the
  // value that was truncated.
  for (int64_t i = -512; i <= 512; ++i) {
    const TestValue original_value(i);
    const uint8_t truncated = original_value.lower_8_bits();
    const TestValue reference(i + 1);
    ASSERT_EQ(original_value, reference.Expand(truncated)) << "i=" << i;
  }

  // Test cases where the difference between the original value and the fixed
  // reference is within the range [-128,+127].  The truncated value should
  // always be re-expanded to the original value.
  for (int64_t bias = -5; bias <= 5; ++bias) {
    for (int64_t i = -128; i <= 127; ++i) {
      const TestValue original_value(bias + i);
      const uint8_t truncated = original_value.lower_8_bits();
      const TestValue reference(bias);
      ASSERT_EQ(original_value, reference.Expand(truncated)) << "bias=" << bias
                                                             << ", i=" << i;
    }
  }

  // Test cases where the difference between the original value and the fixed
  // reference is within the range [+128,+255].  When the truncated value is
  // re-expanded, it should be 256 less than the original value.
  for (int64_t bias = -5; bias <= 5; ++bias) {
    for (int64_t i = 128; i <= 255; ++i) {
      // Example: Let |original_value| be 192.  Then, the truncated 8-bit value
      // will be 0xc0.  When a |reference| of zero is asked to expand 0xc0 back
      // to the original value, it should produce -64 since -64 is closer to
      // |reference| than 192.
      const TestValue original_value(bias + i);
      const uint8_t truncated = original_value.lower_8_bits();
      const TestValue reexpanded_value(bias + i - 256);
      ASSERT_EQ(reexpanded_value.lower_8_bits(), truncated);
      const TestValue reference(bias);
      ASSERT_EQ(reexpanded_value, reference.Expand(truncated))
          << "bias=" << bias << ", i=" << i;
    }
  }

  // Test cases where the difference between the original value and the fixed
  // reference is within the range [-256,-129].  When the truncated value is
  // re-expanded, it should be 256 more than the original value.
  for (int64_t bias = -5; bias <= 5; ++bias) {
    for (int64_t i = -256; i <= -129; ++i) {
      // Example: Let |original_value| be -192.  Then, the truncated 8-bit value
      // will be 0x40.  When a |reference| of zero is asked to expand 0x40 back
      // to the original value, it should produce 64 since 64 is closer to the
      // |reference| than -192.
      const TestValue original_value(bias + i);
      const uint8_t truncated = original_value.lower_8_bits();
      const TestValue reexpanded_value(bias + i + 256);
      ASSERT_EQ(reexpanded_value.lower_8_bits(), truncated);
      const TestValue reference(bias);
      ASSERT_EQ(reexpanded_value, reference.Expand(truncated))
          << "bias=" << bias << ", i=" << i;
    }
  }
}

}  // namespace cast
}  // namespace media
}  // namespace cobalt
