// Copyright 2020 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/shared/starboard/player/filter/testing/video_decoder_test_fixture.h"

#include <algorithm>
#include <deque>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <vector>

#include "starboard/common/condition_variable.h"
#include "starboard/common/mutex.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/common/string.h"
#include "starboard/configuration_constants.h"
#include "starboard/drm.h"
#include "starboard/media.h"
#include "starboard/memory.h"
#include "starboard/shared/starboard/media/media_util.h"
#include "starboard/shared/starboard/player/filter/stub_player_components_factory.h"
#include "starboard/shared/starboard/player/filter/testing/test_util.h"
#include "starboard/shared/starboard/player/filter/video_decoder_internal.h"
#include "starboard/shared/starboard/player/job_queue.h"
#include "starboard/shared/starboard/player/video_dmp_reader.h"
#include "starboard/testing/fake_graphics_context_provider.h"
#include "starboard/thread.h"
#include "starboard/time.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace shared {
namespace starboard {
namespace player {
namespace filter {
namespace testing {
namespace {

using ::starboard::testing::FakeGraphicsContextProvider;
using ::std::placeholders::_1;
using ::std::placeholders::_2;
using video_dmp::VideoDmpReader;

}  // namespace

VideoDecoderTestFixture::VideoDecoderTestFixture(
    JobQueue* job_queue,
    FakeGraphicsContextProvider* fake_graphics_context_provider,
    const char* test_filename,
    SbPlayerOutputMode output_mode,
    bool using_stub_decoder)
    : job_queue_(job_queue),
      fake_graphics_context_provider_(fake_graphics_context_provider),
      test_filename_(test_filename),
      output_mode_(output_mode),
      using_stub_decoder_(using_stub_decoder),
      dmp_reader_(ResolveTestFileName(test_filename).c_str(),
                  VideoDmpReader::kEnableReadOnDemand) {
  SB_DCHECK(job_queue_);
  SB_DCHECK(fake_graphics_context_provider_);
  SB_LOG(INFO) << "Testing " << test_filename_ << ", output mode "
               << output_mode_
               << (using_stub_decoder_ ? " with stub video decoder." : ".");
}

void VideoDecoderTestFixture::Initialize() {
  ASSERT_NE(dmp_reader_.video_codec(), kSbMediaVideoCodecNone);
  ASSERT_GT(dmp_reader_.number_of_video_buffers(), 0);
  ASSERT_TRUE(GetVideoInputBuffer(0)->video_sample_info().is_key_frame);

  SbPlayerOutputMode output_mode = output_mode_;
  ASSERT_TRUE(VideoDecoder::OutputModeSupported(
      output_mode, dmp_reader_.video_codec(), kSbDrmSystemInvalid));

  PlayerComponents::Factory::CreationParameters creation_parameters(
      dmp_reader_.video_codec(),
#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
      GetVideoInputBuffer(0)->video_sample_info(),
#endif  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
      &player_, output_mode,
      fake_graphics_context_provider_->decoder_target_provider(), nullptr);

  scoped_ptr<PlayerComponents::Factory> factory;
  if (using_stub_decoder_) {
    factory = StubPlayerComponentsFactory::Create();
  } else {
    factory = PlayerComponents::Factory::Create();
  }
  std::string error_message;
  ASSERT_TRUE(factory->CreateSubComponents(
      creation_parameters, nullptr, nullptr, &video_decoder_,
      &video_render_algorithm_, &video_renderer_sink_, &error_message));
  ASSERT_TRUE(video_decoder_);

  if (video_renderer_sink_) {
    video_renderer_sink_->SetRenderCB(
        std::bind(&VideoDecoderTestFixture::Render, this, _1));
  }

  video_decoder_->Initialize(
      std::bind(&VideoDecoderTestFixture::OnDecoderStatusUpdate, this, _1, _2),
      std::bind(&VideoDecoderTestFixture::OnError, this));
  if (HasPendingEvents()) {
    bool error_occurred = false;
    ASSERT_NO_FATAL_FAILURE(DrainOutputs(&error_occurred));
    ASSERT_FALSE(error_occurred);
  }
}

void VideoDecoderTestFixture::OnDecoderStatusUpdate(
    VideoDecoder::Status status,
    const scoped_refptr<VideoFrame>& frame) {
  ScopedLock scoped_lock(mutex_);
  // TODO: Ensure that this is only called during dtor or Reset().
  if (status == VideoDecoder::kReleaseAllFrames) {
    SB_DCHECK(!frame);
    event_queue_.clear();
    decoded_frames_.clear();
    return;
  } else if (status == VideoDecoder::kNeedMoreInput) {
    event_queue_.push_back(Event(kNeedMoreInput, frame));
  } else if (status == VideoDecoder::kBufferFull) {
    event_queue_.push_back(Event(kBufferFull, frame));
  } else {
    event_queue_.push_back(Event(kError, frame));
  }
}

void VideoDecoderTestFixture::OnError() {
  ScopedLock scoped_lock(mutex_);
  event_queue_.push_back(Event(kError, NULL));
}

#if SB_HAS(GLES2)
void VideoDecoderTestFixture::AssertInvalidDecodeTarget() {
  if (output_mode_ == kSbPlayerOutputModeDecodeToTexture &&
      !using_stub_decoder_) {
    volatile bool is_decode_target_valid = true;
    fake_graphics_context_provider_->RunOnGlesContextThread([&]() {
      SbDecodeTarget decode_target = video_decoder_->GetCurrentDecodeTarget();
      is_decode_target_valid = SbDecodeTargetIsValid(decode_target);
      SbDecodeTargetRelease(decode_target);
    });
    ASSERT_FALSE(is_decode_target_valid);
  }
}
#endif  // SB_HAS(GLES2)

void VideoDecoderTestFixture::WaitForNextEvent(Event* event,
                                               SbTimeMonotonic timeout) {
  ASSERT_TRUE(event);

  SbTimeMonotonic start = SbTimeGetMonotonicNow();
  do {
    job_queue_->RunUntilIdle();
    GetDecodeTargetWhenSupported();
    {
      ScopedLock scoped_lock(mutex_);
      if (!event_queue_.empty()) {
        *event = event_queue_.front();
        event_queue_.pop_front();
        if (event->status == kNeedMoreInput) {
          need_more_input_ = true;
        } else if (event->status == kBufferFull) {
          if (!end_of_stream_written_) {
            ASSERT_FALSE(need_more_input_);
          }
        }
        return;
      }
    }
    SbThreadSleep(kSbTimeMillisecond);
  } while (SbTimeGetMonotonicNow() - start < timeout);
  event->status = kTimeout;
}

bool VideoDecoderTestFixture::HasPendingEvents() {
  const SbTime kDelay = 5 * kSbTimeMillisecond;
  SbThreadSleep(kDelay);
  ScopedLock scoped_lock(mutex_);
  return !event_queue_.empty();
}

void VideoDecoderTestFixture::GetDecodeTargetWhenSupported() {
#if SB_HAS(GLES2)
  if (output_mode_ == kSbPlayerOutputModeDecodeToTexture &&
      !using_stub_decoder_) {
    fake_graphics_context_provider_->RunOnGlesContextThread([&]() {
      SbDecodeTargetRelease(video_decoder_->GetCurrentDecodeTarget());
    });
  }
#endif  // SB_HAS(GLES2)
}

void VideoDecoderTestFixture::AssertValidDecodeTargetWhenSupported() {
#if SB_HAS(GLES2)
  volatile bool is_decode_target_valid = false;
  if (output_mode_ == kSbPlayerOutputModeDecodeToTexture &&
      !using_stub_decoder_) {
    fake_graphics_context_provider_->RunOnGlesContextThread([&]() {
      SbDecodeTarget decode_target = video_decoder_->GetCurrentDecodeTarget();
      is_decode_target_valid = SbDecodeTargetIsValid(decode_target);
      SbDecodeTargetRelease(decode_target);
    });
    ASSERT_TRUE(is_decode_target_valid);
  }
#endif  // SB_HAS(GLES2)
}

// This has to be called when the decoder is just initialized/reseted or when
// status is |kNeedMoreInput|.
void VideoDecoderTestFixture::WriteSingleInput(size_t index) {
  ASSERT_TRUE(need_more_input_);
  ASSERT_LT(index, dmp_reader_.number_of_video_buffers());

  auto input_buffer = GetVideoInputBuffer(index);
  {
    ScopedLock scoped_lock(mutex_);
    need_more_input_ = false;
    outstanding_inputs_.insert(input_buffer->timestamp());
  }

  video_decoder_->WriteInputBuffer(input_buffer);
}

void VideoDecoderTestFixture::WriteEndOfStream() {
  {
    ScopedLock scoped_lock(mutex_);
    end_of_stream_written_ = true;
  }
  video_decoder_->WriteEndOfStream();
}

void VideoDecoderTestFixture::WriteMultipleInputs(
    size_t start_index,
    size_t number_of_inputs_to_write,
    EventCB event_cb) {
  ASSERT_LE(start_index + number_of_inputs_to_write,
            dmp_reader_.number_of_video_buffers());

  ASSERT_NO_FATAL_FAILURE(WriteSingleInput(start_index));
  ++start_index;
  --number_of_inputs_to_write;

  while (number_of_inputs_to_write > 0) {
    Event event;
    ASSERT_NO_FATAL_FAILURE(WaitForNextEvent(&event));
    if (event.status == kNeedMoreInput) {
      ASSERT_NO_FATAL_FAILURE(WriteSingleInput(start_index));
      ++start_index;
      --number_of_inputs_to_write;
    } else if (event.status == kError || event.status == kTimeout) {
      // Assume that the caller does't expect an error when |event_cb| isn't
      // provided.
      ASSERT_TRUE(event_cb);
      bool continue_process = true;
      event_cb(event, &continue_process);
      ASSERT_FALSE(continue_process);
      return;
    } else {
      ASSERT_EQ(event.status, kBufferFull);
    }
    if (event.frame) {
      ASSERT_FALSE(event.frame->is_end_of_stream());
      if (!decoded_frames_.empty()) {
        ASSERT_LT(decoded_frames_.back()->timestamp(),
                  event.frame->timestamp());
      }
      decoded_frames_.push_back(event.frame);
      ASSERT_TRUE(AlmostEqualTime(*outstanding_inputs_.begin(),
                                  event.frame->timestamp()));
      outstanding_inputs_.erase(outstanding_inputs_.begin());
    }
    if (event_cb) {
      bool continue_process = true;
      event_cb(event, &continue_process);
      if (!continue_process) {
        return;
      }
    }
  }
}

void VideoDecoderTestFixture::DrainOutputs(bool* error_occurred,
                                           EventCB event_cb) {
  if (error_occurred) {
    *error_occurred = false;
  }

  bool end_of_stream_decoded = false;

  while (!end_of_stream_decoded) {
    Event event;
    ASSERT_NO_FATAL_FAILURE(WaitForNextEvent(&event));
    if (event.status == kError || event.status == kTimeout) {
      if (error_occurred) {
        *error_occurred = true;
      } else {
        FAIL();
      }
      return;
    }
    if (event.frame) {
      if (event.frame->is_end_of_stream()) {
        end_of_stream_decoded = true;
        if (!outstanding_inputs_.empty()) {
          SB_LOG(WARNING) << "|outstanding_inputs_| is not empty.";
          if (error_occurred) {
            *error_occurred = true;
          } else {
            // |error_occurred| is NULL indicates that the caller doesn't
            // expect an error, use the following redundant ASSERT to trigger
            // a failure.
            ASSERT_TRUE(outstanding_inputs_.empty());
          }
        }
      } else {
        if (!decoded_frames_.empty()) {
          ASSERT_LT(decoded_frames_.back()->timestamp(),
                    event.frame->timestamp());
        }
        decoded_frames_.push_back(event.frame);
        ASSERT_TRUE(AlmostEqualTime(*outstanding_inputs_.begin(),
                                    event.frame->timestamp()));
        outstanding_inputs_.erase(outstanding_inputs_.begin());
      }
    }
    if (event_cb) {
      bool continue_process = true;
      event_cb(event, &continue_process);
      if (!continue_process) {
        return;
      }
    }
  }
}

void VideoDecoderTestFixture::ResetDecoderAndClearPendingEvents() {
  video_decoder_->Reset();
  ScopedLock scoped_lock(mutex_);
  event_queue_.clear();
  need_more_input_ = true;
  end_of_stream_written_ = false;
  outstanding_inputs_.clear();
  decoded_frames_.clear();
}

scoped_refptr<InputBuffer> VideoDecoderTestFixture::GetVideoInputBuffer(
    size_t index) {
  auto video_sample_info =
      dmp_reader_.GetPlayerSampleInfo(kSbMediaTypeVideo, index);
#if SB_API_VERSION >= 11
  auto input_buffer =
      new InputBuffer(StubDeallocateSampleFunc, NULL, NULL, video_sample_info);
#else   // SB_API_VERSION >= 11
  auto input_buffer =
      new InputBuffer(kSbMediaTypeVideo, StubDeallocateSampleFunc, NULL, NULL,
                      video_sample_info, NULL);
#endif  // SB_API_VERSION >= 11
  auto iter = invalid_inputs_.find(index);
  if (iter != invalid_inputs_.end()) {
    std::vector<uint8_t> content(input_buffer->size(), iter->second);
    // Replace the content with invalid data.
    input_buffer->SetDecryptedContent(content.data(),
                                      static_cast<int>(content.size()));
  }
  return input_buffer;
}

}  // namespace testing
}  // namespace filter
}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard
