// 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/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) {}

#if SB_HAS(PLAYER_ERROR_MESSAGE)
void DummyErrorFunc(SbPlayer player,
                    void* context,
                    SbPlayerError error,
                    const char* message) {}
#endif  // SB_HAS(PLAYER_ERROR_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.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,
#if SB_API_VERSION < 10
                        SB_PLAYER_NO_DURATION,
#endif  // SB_API_VERSION < 10
                        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,
#if SB_HAS(PLAYER_ERROR_MESSAGE)
                        DummyErrorFunc,
#endif  // SB_HAS(PLAYER_ERROR_MESSAGE)
                        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);
  }
}

#if SB_API_VERSION >= 10
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_ERROR_MESSAGE)

#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)

#endif  // SB_HAS(PLAYER_ERROR_MESSAGE)
  }
}
#endif  // SB_API_VERSION >= 10

#if SB_HAS(AUDIOLESS_VIDEO)
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);
  }
}
#endif  // SB_HAS(AUDIOLESS_VIDEO)

#if SB_API_VERSION >= 10
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,
#if SB_HAS(AC3_AUDIO)
    kSbMediaAudioCodecAc3,
    kSbMediaAudioCodecEac3,
#endif  // SB_HAS(AC3_AUDIO)
    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]:
#if SB_HAS(AC3_AUDIO)
    case kAudioCodecs[4]:
    case kAudioCodecs[5]:
#endif  // SB_HAS(AC3_AUDIO)
      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);
  }
}
#endif  // SB_API_VERSION >= 10

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