// Copyright 2016 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 <vector>

#include "starboard/blitter.h"
#include "starboard/configuration_constants.h"
#include "starboard/decode_target.h"
#include "starboard/nplb/player_creation_param_helpers.h"
#include "starboard/player.h"
#include "starboard/testing/fake_graphics_context_provider.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

using ::starboard::testing::FakeGraphicsContextProvider;

class SbPlayerTest : public ::testing::Test {
 protected:
  FakeGraphicsContextProvider fake_graphics_context_provider_;
};

void DummyDeallocateSampleFunc(SbPlayer player,
                               void* context,
                               const void* sample_buffer) {}

void DummyDecoderStatusFunc(SbPlayer player,
                            void* context,
                            SbMediaType type,
                            SbPlayerDecoderState state,
                            int ticket) {}

void DummyStatusFunc(SbPlayer player,
                     void* context,
                     SbPlayerState state,
                     int ticket) {}

void DummyErrorFunc(SbPlayer player,
                    void* context,
                    SbPlayerError error,
                    const char* message) {}

SbPlayer CallSbPlayerCreate(
    SbWindow window,
    SbMediaVideoCodec video_codec,
    SbMediaAudioCodec audio_codec,
    SbDrmSystem drm_system,
    const SbMediaAudioSampleInfo* audio_sample_info,
    const char* max_video_capabilities,
    SbPlayerDeallocateSampleFunc sample_deallocate_func,
    SbPlayerDecoderStatusFunc decoder_status_func,
    SbPlayerStatusFunc player_status_func,
    void* context,
    SbPlayerOutputMode output_mode,
    SbDecodeTargetGraphicsContextProvider* context_provider) {
#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)

  if (audio_sample_info) {
    SB_CHECK(audio_sample_info->codec == audio_codec);
  } else {
    SB_CHECK(audio_codec == kSbMediaAudioCodecNone);
  }

  SbPlayerCreationParam creation_param =
      CreatePlayerCreationParam(audio_codec, video_codec);
  if (audio_sample_info) {
    creation_param.audio_sample_info = *audio_sample_info;
  }
  creation_param.drm_system = drm_system;
  creation_param.output_mode = output_mode;
  creation_param.video_sample_info.max_video_capabilities =
      max_video_capabilities;

  return SbPlayerCreate(window, &creation_param, sample_deallocate_func,
                        decoder_status_func, player_status_func, DummyErrorFunc,
                        context, context_provider);

#else  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)

  return SbPlayerCreate(window, video_codec, audio_codec,
                        kSbDrmSystemInvalid, audio_sample_info,
#if SB_API_VERSION >= 11
                        max_video_capabilities,
#endif  // SB_API_VERSION >= 11
                        sample_deallocate_func, decoder_status_func,
                        player_status_func,
                        DummyErrorFunc,
                        context, output_mode, context_provider);

#endif  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
}

bool IsOutputModeSupported(SbPlayerOutputMode output_mode,
                           SbMediaVideoCodec codec) {
#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
  SbPlayerCreationParam creation_param =
      CreatePlayerCreationParam(kSbMediaAudioCodecNone, codec);
  creation_param.output_mode = output_mode;
  return SbPlayerGetPreferredOutputMode(&creation_param) == output_mode;
#else   // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
  return SbPlayerOutputModeSupported(output_mode, codec, kSbDrmSystemInvalid);
#endif  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
}

TEST_F(SbPlayerTest, SunnyDay) {
  SbMediaAudioSampleInfo audio_sample_info =
      CreateAudioSampleInfo(kSbMediaAudioCodecAac);
  SbMediaVideoCodec kVideoCodec = kSbMediaVideoCodecH264;

  SbPlayerOutputMode output_modes[] = {kSbPlayerOutputModeDecodeToTexture,
                                       kSbPlayerOutputModePunchOut};

  for (int i = 0; i < SB_ARRAY_SIZE_INT(output_modes); ++i) {
    SbPlayerOutputMode output_mode = output_modes[i];

    if (!IsOutputModeSupported(output_mode, kVideoCodec)) {
      continue;
    }
    SbPlayer player = CallSbPlayerCreate(
        fake_graphics_context_provider_.window(), kSbMediaVideoCodecH264,
        kSbMediaAudioCodecAac, kSbDrmSystemInvalid, &audio_sample_info,
        "" /* max_video_capabilities */, DummyDeallocateSampleFunc,
        DummyDecoderStatusFunc, DummyStatusFunc, NULL /* context */,
        output_mode, fake_graphics_context_provider_.decoder_target_provider());
    EXPECT_TRUE(SbPlayerIsValid(player));

    if (output_mode == kSbPlayerOutputModeDecodeToTexture) {
      SbDecodeTarget current_frame = SbPlayerGetCurrentFrame(player);
    }

    SbPlayerDestroy(player);
  }
}

TEST_F(SbPlayerTest, NullCallbacks) {
  SbMediaAudioSampleInfo audio_sample_info =
      CreateAudioSampleInfo(kSbMediaAudioCodecAac);
  SbMediaVideoCodec kVideoCodec = kSbMediaVideoCodecH264;

  SbPlayerOutputMode output_modes[] = {kSbPlayerOutputModeDecodeToTexture,
                                       kSbPlayerOutputModePunchOut};

  for (int i = 0; i < SB_ARRAY_SIZE_INT(output_modes); ++i) {
    SbPlayerOutputMode output_mode = output_modes[i];
    if (!IsOutputModeSupported(output_mode, kVideoCodec)) {
      continue;
    }

    {
      SbPlayer player = CallSbPlayerCreate(
          fake_graphics_context_provider_.window(), kSbMediaVideoCodecH264,
          kSbMediaAudioCodecAac, kSbDrmSystemInvalid, &audio_sample_info,
          "" /* max_video_capabilities */, NULL /* deallocate_sample_func */,
          DummyDecoderStatusFunc, DummyStatusFunc, NULL /* context */,
          output_mode,
          fake_graphics_context_provider_.decoder_target_provider());
      EXPECT_FALSE(SbPlayerIsValid(player));

      SbPlayerDestroy(player);
    }

    {
      SbPlayer player = CallSbPlayerCreate(
          fake_graphics_context_provider_.window(), kSbMediaVideoCodecH264,
          kSbMediaAudioCodecAac, kSbDrmSystemInvalid, &audio_sample_info,
          "" /* max_video_capabilities */, DummyDeallocateSampleFunc,
          NULL /* decoder_status_func */, DummyStatusFunc, NULL /* context */,
          output_mode,
          fake_graphics_context_provider_.decoder_target_provider());
      EXPECT_FALSE(SbPlayerIsValid(player));

      SbPlayerDestroy(player);
    }

    {
      SbPlayer player = CallSbPlayerCreate(
          fake_graphics_context_provider_.window(), kSbMediaVideoCodecH264,
          kSbMediaAudioCodecAac, kSbDrmSystemInvalid, &audio_sample_info,
          "" /* max_video_capabilities */, DummyDeallocateSampleFunc,
          DummyDecoderStatusFunc, NULL /*status_func */, NULL /* context */,
          output_mode,
          fake_graphics_context_provider_.decoder_target_provider());
      EXPECT_FALSE(SbPlayerIsValid(player));

      SbPlayerDestroy(player);
    }

#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)

    {
      SbPlayerCreationParam creation_param = CreatePlayerCreationParam(
          kSbMediaAudioCodecAac, kSbMediaVideoCodecH264);

      SbPlayer player = SbPlayerCreate(
          fake_graphics_context_provider_.window(), &creation_param,
          DummyDeallocateSampleFunc, DummyDecoderStatusFunc, DummyStatusFunc,
          NULL /* error_func */, NULL /* context */,
          fake_graphics_context_provider_.decoder_target_provider());
      EXPECT_FALSE(SbPlayerIsValid(player));

      SbPlayerDestroy(player);
    }

#else  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)

    {
      SbPlayer player = SbPlayerCreate(
          fake_graphics_context_provider_.window(), kSbMediaVideoCodecH264,
          kSbMediaAudioCodecAac,
          kSbDrmSystemInvalid, &audio_sample_info,
#if SB_API_VERSION >= 11
          NULL /* max_video_capabilities */,
#endif  // SB_API_VERSION >= 11
          DummyDeallocateSampleFunc, DummyDecoderStatusFunc, DummyStatusFunc,
          NULL /*error_func */, NULL /* context */, output_mode,
          fake_graphics_context_provider_.decoder_target_provider());
      EXPECT_FALSE(SbPlayerIsValid(player));

      SbPlayerDestroy(player);
    }

#endif  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
  }
}

TEST_F(SbPlayerTest, Audioless) {
  SbMediaVideoCodec kVideoCodec = kSbMediaVideoCodecH264;

  SbPlayerOutputMode output_modes[] = {kSbPlayerOutputModeDecodeToTexture,
                                       kSbPlayerOutputModePunchOut};

  for (int i = 0; i < SB_ARRAY_SIZE_INT(output_modes); ++i) {
    SbPlayerOutputMode output_mode = output_modes[i];
    if (!IsOutputModeSupported(output_mode, kVideoCodec)) {
      continue;
    }

    SbPlayer player = CallSbPlayerCreate(
        fake_graphics_context_provider_.window(), kVideoCodec,
        kSbMediaAudioCodecNone, kSbDrmSystemInvalid,
        NULL /* audio_sample_info */, "" /* max_video_capabilities */,
        DummyDeallocateSampleFunc, DummyDecoderStatusFunc, DummyStatusFunc,
        NULL /* context */, output_mode,
        fake_graphics_context_provider_.decoder_target_provider());
    EXPECT_TRUE(SbPlayerIsValid(player));

    if (output_mode == kSbPlayerOutputModeDecodeToTexture) {
      SbDecodeTarget current_frame = SbPlayerGetCurrentFrame(player);
    }

    SbPlayerDestroy(player);
  }
}

TEST_F(SbPlayerTest, AudioOnly) {
  SbMediaAudioSampleInfo audio_sample_info =
      CreateAudioSampleInfo(kSbMediaAudioCodecAac);
  SbMediaAudioCodec kAudioCodec = kSbMediaAudioCodecAac;
  SbMediaVideoCodec kVideoCodec = kSbMediaVideoCodecH264;

  SbPlayerOutputMode output_modes[] = {kSbPlayerOutputModeDecodeToTexture,
                                       kSbPlayerOutputModePunchOut};

  for (int i = 0; i < SB_ARRAY_SIZE_INT(output_modes); ++i) {
    SbPlayerOutputMode output_mode = output_modes[i];
    if (!IsOutputModeSupported(output_mode, kVideoCodec)) {
      continue;
    }

    SbPlayer player = CallSbPlayerCreate(
        fake_graphics_context_provider_.window(), kSbMediaVideoCodecNone,
        kAudioCodec, kSbDrmSystemInvalid, &audio_sample_info,
        "" /* max_video_capabilities */, DummyDeallocateSampleFunc,
        DummyDecoderStatusFunc, DummyStatusFunc, NULL /* context */,
        output_mode, fake_graphics_context_provider_.decoder_target_provider());
    EXPECT_TRUE(SbPlayerIsValid(player));

    if (output_mode == kSbPlayerOutputModeDecodeToTexture) {
      SbDecodeTarget current_frame = SbPlayerGetCurrentFrame(player);
    }

    SbPlayerDestroy(player);
  }
}

TEST_F(SbPlayerTest, MultiPlayer) {
  SbMediaAudioSampleInfo audio_sample_info =
      CreateAudioSampleInfo(kSbMediaAudioCodecAac);
  SbDrmSystem kDrmSystem = kSbDrmSystemInvalid;

  constexpr SbPlayerOutputMode kOutputModes[] = {
      kSbPlayerOutputModeDecodeToTexture, kSbPlayerOutputModePunchOut};

  constexpr SbMediaAudioCodec kAudioCodecs[] = {
    kSbMediaAudioCodecNone,

    kSbMediaAudioCodecAac,
    kSbMediaAudioCodecAc3,
    kSbMediaAudioCodecEac3,
    kSbMediaAudioCodecOpus,
    kSbMediaAudioCodecVorbis,
  };

  // TODO: turn this into a macro.
  // Perform a check to determine if new audio codecs have been added to the
  // SbMediaAudioCodec enum, but not the array |audio_codecs|. If the compiler
  // warns about a missing case here, the value must be added to |kAudioCodecs|.
  SbMediaAudioCodec audio_codec = kAudioCodecs[0];
  switch (audio_codec) {
    case kAudioCodecs[0]:
    case kAudioCodecs[1]:
    case kAudioCodecs[2]:
    case kAudioCodecs[3]:
    case kAudioCodecs[4]:
    case kAudioCodecs[5]:
      break;
  }

  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,
  };

  // TODO: turn this into a macro.
  // Perform a check to determine if new video codecs have been added to the
  // SbMediaVideoCodec enum, but not the array |video_codecs|. If the compiler
  // warns about a missing case here, the value must be added to |kVideoCodecs|.
  SbMediaVideoCodec video_codec = kVideoCodecs[0];
  switch (video_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;
  }

  const int kMaxPlayersPerConfig = 16;
  std::vector<SbPlayer> created_players;
  int number_of_players = 0;
  for (int i = 0; i < kMaxPlayersPerConfig; ++i) {
    for (int j = 0; j < SB_ARRAY_SIZE_INT(kOutputModes); ++j) {
      for (int k = 0; k < SB_ARRAY_SIZE_INT(kAudioCodecs); ++k) {
        for (int l = 0; l < SB_ARRAY_SIZE_INT(kVideoCodecs); ++l) {
#if SB_API_VERSION >= 11
          audio_sample_info.codec = kAudioCodecs[k];
#endif  // SB_API_VERSION >= 11
          created_players.push_back(CallSbPlayerCreate(
              fake_graphics_context_provider_.window(), kVideoCodecs[l],
              kAudioCodecs[k], kSbDrmSystemInvalid, &audio_sample_info,
              "" /* max_video_capabilities */, DummyDeallocateSampleFunc,
              DummyDecoderStatusFunc, DummyStatusFunc, NULL /* context */,
              kOutputModes[j],
              fake_graphics_context_provider_.decoder_target_provider()));
          if (!SbPlayerIsValid(created_players.back())) {
            created_players.pop_back();
          }
        }
      }
    }
    if (created_players.size() == number_of_players) {
      break;
    }
    number_of_players = created_players.size();
  }
  SB_DLOG(INFO) << "Created " << number_of_players << " players in total.";
  for (auto player : created_players) {
    SbPlayerDestroy(player);
  }
}

}  // namespace
}  // namespace nplb
}  // namespace starboard
