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

#include "starboard/drm.h"
#include "starboard/nplb/drm_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

TEST(SbDrmTest, AnySupportedKeySystems) {
  bool any_supported_key_systems = false;
  for (int i = 0; i < SB_ARRAY_SIZE_INT(kKeySystems); ++i) {
    const char* key_system = kKeySystems[i];
    SbDrmSystem drm_system = CreateDummyDrmSystem(key_system);
    if (SbDrmSystemIsValid(drm_system)) {
      SB_DLOG(INFO) << "Drm system with key system " << key_system
                    << " is valid.";
    } else {
      SB_DLOG(INFO) << "Drm system with key system " << key_system
                    << " is NOT valid.";
    }
    any_supported_key_systems |= SbDrmSystemIsValid(drm_system);
    SbDrmDestroySystem(drm_system);
  }
  EXPECT_TRUE(any_supported_key_systems) << " no DRM key systems supported";
}

#if SB_API_VERSION >= 10
TEST(SbDrmTest, NullCallbacks) {
  for (int i = 0; i < SB_ARRAY_SIZE_INT(kKeySystems); ++i) {
    const char* key_system = kKeySystems[i];
    {
      SbDrmSystem drm_system = SbDrmCreateSystem(
          key_system, NULL /* context */,
          NULL /* session_update_request_func */, DummySessionUpdatedFunc,
          DummySessionKeyStatusesChangedFunc, DummyServerCertificateUpdatedFunc,
          DummySessionClosedFunc);
      EXPECT_FALSE(SbDrmSystemIsValid(drm_system));
      SbDrmDestroySystem(drm_system);
    }
    {
      SbDrmSystem drm_system = SbDrmCreateSystem(
          key_system, NULL /* context */, DummySessionUpdateRequestFunc,
          NULL /*session_updated_func */, DummySessionKeyStatusesChangedFunc,
          DummyServerCertificateUpdatedFunc, DummySessionClosedFunc);
      EXPECT_FALSE(SbDrmSystemIsValid(drm_system));
      SbDrmDestroySystem(drm_system);
    }
    {
      SbDrmSystem drm_system = SbDrmCreateSystem(
          key_system, NULL /* context */, DummySessionUpdateRequestFunc,
          DummySessionUpdatedFunc, NULL /* session_key_statuses_changed_func */,
          DummyServerCertificateUpdatedFunc, DummySessionClosedFunc);
      EXPECT_FALSE(SbDrmSystemIsValid(drm_system));
      SbDrmDestroySystem(drm_system);
    }
    {
      SbDrmSystem drm_system = SbDrmCreateSystem(
          key_system, NULL /* context */, DummySessionUpdateRequestFunc,
          DummySessionUpdatedFunc, DummySessionKeyStatusesChangedFunc,
          NULL /* server_certificatd_updated_func */, DummySessionClosedFunc);
      EXPECT_FALSE(SbDrmSystemIsValid(drm_system));
      SbDrmDestroySystem(drm_system);
    }
    {
      SbDrmSystem drm_system = SbDrmCreateSystem(
          key_system, NULL /* context */, DummySessionUpdateRequestFunc,
          DummySessionUpdatedFunc, DummySessionKeyStatusesChangedFunc,
          DummyServerCertificateUpdatedFunc, NULL /* session_closed_func */);
      EXPECT_FALSE(SbDrmSystemIsValid(drm_system));
      SbDrmDestroySystem(drm_system);
    }
  }
}

TEST(SbDrmTest, MultiDrm) {
  const int kMaxPlayersPerKeySystem = 16;
  std::vector<SbDrmSystem> created_drm_systems;
  int number_of_drm_systems = 0;
  for (int i = 0; i < kMaxPlayersPerKeySystem; ++i) {
    for (int j = 0; j < SB_ARRAY_SIZE_INT(kKeySystems); ++j) {
      const char* key_system = kKeySystems[j];
      created_drm_systems.push_back(CreateDummyDrmSystem(key_system));
      if (!SbDrmSystemIsValid(created_drm_systems.back())) {
        created_drm_systems.pop_back();
      }
    }
    if (created_drm_systems.size() == number_of_drm_systems) {
      break;
    }
    number_of_drm_systems = created_drm_systems.size();
  }
  SB_DLOG(INFO) << "Created " << number_of_drm_systems
                << " DRM systems in total.";
  for (auto drm_system : created_drm_systems) {
    SbDrmDestroySystem(drm_system);
  }
}
#endif  // SB_API_VERSION >= 10

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