// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/media.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

constexpr int kVideoResolutions[][2] = {
    {kSbMediaVideoResolutionDimensionInvalid,
     kSbMediaVideoResolutionDimensionInvalid},
    {640, 480},
    {1280, 720},
    {1920, 1080},
    {2560, 1440},
    {3840, 2160},
};

constexpr int kBitsPerPixelValues[] = {
    kSbMediaBitsPerPixelInvalid, 8, 10, 12,
};

constexpr SbMediaVideoCodec kVideoCodecs[] = {
    kSbMediaVideoCodecNone,

    kSbMediaVideoCodecH264,   kSbMediaVideoCodecH265, kSbMediaVideoCodecMpeg2,
    kSbMediaVideoCodecTheora, kSbMediaVideoCodecVc1,
#if SB_API_VERSION < 11
    kSbMediaVideoCodecVp10,
#else   // SB_API_VERSION < 11
    kSbMediaVideoCodecAv1,
#endif  // SB_API_VERSION < 11
    kSbMediaVideoCodecVp8,    kSbMediaVideoCodecVp9,
};

constexpr SbMediaType kMediaTypes[] = {
    kSbMediaTypeAudio, kSbMediaTypeVideo,
};

}  // namespace

TEST(SbMediaBufferTest, VideoCodecs) {
  // Perform a check to determine if new codecs have been added to the
  // enum, but not the array. If the compiler warns about a missing case here,
  // the value must be added to the array and the switch case.
  SbMediaVideoCodec codec = kVideoCodecs[0];
  switch (codec) {
    case kVideoCodecs[0]:
    case kVideoCodecs[1]:
    case kVideoCodecs[2]:
    case kVideoCodecs[3]:
    case kVideoCodecs[4]:
    case kVideoCodecs[5]:
    case kVideoCodecs[6]:
    case kVideoCodecs[7]:
    case kVideoCodecs[8]:
      break;
  }
}

TEST(SbMediaBufferTest, MediaTypes) {
  // Perform a check to determine if new types have been added to the
  // enum, but not the array. If the compiler warns about a missing case here,
  // the value must be added to the array and the switch case.
  SbMediaType type = kMediaTypes[0];
  switch (type) {
    case kMediaTypes[0]:
    case kMediaTypes[1]:
      break;
  }
}

TEST(SbMediaBufferTest, Alignment) {
  for (auto type : kMediaTypes) {
    int alignment = SbMediaGetBufferAlignment(type);
    // TODO: This currently accepts 0 or a power of 2. We should disallow 0 here
    // when we change the default value to be 1 instead of 0.
    EXPECT_GE(alignment, 0);
    EXPECT_EQ(alignment & (alignment - 1), 0)
        << "Alignment must always be a power of 2";
  }
}

TEST(SbMediaBufferTest, AllocationUnit) {
  // TODO: impose more bounds.
  EXPECT_GE(SbMediaGetBufferAllocationUnit(), 0);
}

TEST(SbMediaBufferTest, AudioBudget) {
  // TODO: refine this lower bound.
  const int kMinAudioBudget = 1 * 1024 * 1024;
  EXPECT_GT(SbMediaGetAudioBufferBudget(), kMinAudioBudget);
}

TEST(SbMediaBufferTest, GarbageCollectionDurationThreshold) {
  // TODO: impose reasonable bounds here.
  int kMinGarbageCollectionDurationThreshold = 10 * kSbTimeSecond;
  int kMaxGarbageCollectionDurationThreshold = 240 * kSbTimeSecond;
  int threshold = SbMediaGetBufferGarbageCollectionDurationThreshold();
  EXPECT_GE(threshold, kMinGarbageCollectionDurationThreshold);
  EXPECT_LE(threshold, kMaxGarbageCollectionDurationThreshold);
}

TEST(SbMediaBufferTest, InitialCapacity) {
  EXPECT_GE(SbMediaGetInitialBufferCapacity(), 0);
}

TEST(SbMediaBufferTest, MaxCapacity) {
  // TODO: set a reasonable upper bound.
  for (auto resolution : kVideoResolutions) {
    for (auto bits_per_pixel : kBitsPerPixelValues) {
      for (auto codec : kVideoCodecs) {
        EXPECT_GT(SbMediaGetMaxBufferCapacity(codec, resolution[0],
                                              resolution[1], bits_per_pixel),
                  0);
        EXPECT_GE(SbMediaGetMaxBufferCapacity(codec, resolution[0],
                                              resolution[1], bits_per_pixel),
                  SbMediaGetInitialBufferCapacity());
      }
    }
  }
}

TEST(SbMediaBufferTest, Padding) {
  for (auto type : kMediaTypes) {
    EXPECT_GE(SbMediaGetBufferPadding(type), 0);
  }
}

TEST(SbMediaBufferTest, PoolAllocateOnDemand) {
  // Just don't crash.
  SbMediaIsBufferPoolAllocateOnDemand();
}

TEST(SbMediaBufferTest, ProgressiveBudget) {
  const int kMinProgressiveBudget = 8 * 1024 * 1024;
  int audio_budget = SbMediaGetAudioBufferBudget();
  for (auto video_codec : kVideoCodecs) {
    for (auto bits_per_pixel : kBitsPerPixelValues) {
      int video_budget_1080p =
          SbMediaGetVideoBufferBudget(video_codec, 1920, 1080, bits_per_pixel);
      for (auto resolution : kVideoResolutions) {
        int progressive_budget = SbMediaGetProgressiveBufferBudget(
            video_codec, resolution[0], resolution[1], bits_per_pixel);
        EXPECT_LT(progressive_budget, video_budget_1080p + audio_budget)
            << "Progressive budget must be less than sum of 1080p video "
               "budget and audio budget";
        EXPECT_GE(progressive_budget, kMinProgressiveBudget);
      }
    }
  }
}

TEST(SbMediaBufferTest, StorageType) {
  // Just don't crash.
  SbMediaBufferStorageType type = SbMediaGetBufferStorageType();
  switch (type) {
    case kSbMediaBufferStorageTypeMemory:
    case kSbMediaBufferStorageTypeFile:
      return;
  }
  SB_NOTREACHED();
}

TEST(SbMediaBufferTest, UsingMemoryPool) {
  // Just don't crash.
  SbMediaIsBufferUsingMemoryPool();
}

TEST(SbMediaBufferTest, VideoBudget) {
  // TODO: refine this lower bound.
  const int kMinVideoBudget = 1 * 1024 * 1024;
  for (auto codec : kVideoCodecs) {
    for (auto resolution : kVideoResolutions) {
      for (auto bits_per_pixel : kBitsPerPixelValues) {
        EXPECT_GT(SbMediaGetVideoBufferBudget(codec, resolution[0],
                                              resolution[1], bits_per_pixel),
                  kMinVideoBudget);
      }
    }
  }
}
}  // namespace nplb
}  // namespace starboard
