// Copyright 2018 Google Inc. 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/video_decoder_internal.h"

#include <algorithm>
#include <deque>
#include <functional>
#include <set>

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

// This has to be defined in the global namespace as its instance will be used
// as SbPlayer.
struct SbPlayerPrivate {};

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 ::testing::ValuesIn;
using video_dmp::VideoDmpReader;

struct TestParam {
  SbPlayerOutputMode output_mode;
  const char* filename;
};

const SbTimeMonotonic kDefaultWaitForNextEventTimeOut = 5 * kSbTimeSecond;

std::string GetTestInputDirectory() {
  const size_t kPathSize = SB_FILE_MAX_PATH + 1;

  char test_output_path[kPathSize];
  EXPECT_TRUE(SbSystemGetPath(kSbSystemPathSourceDirectory, test_output_path,
                              kPathSize));
  std::string directory_path =
      std::string(test_output_path) + SB_FILE_SEP_CHAR + "starboard" +
      SB_FILE_SEP_CHAR + "shared" + SB_FILE_SEP_CHAR + "starboard" +
      SB_FILE_SEP_CHAR + "player" + SB_FILE_SEP_CHAR + "testdata";

  SB_CHECK(SbDirectoryCanOpen(directory_path.c_str())) << directory_path;
  return directory_path;
}

std::string ResolveTestFileName(const char* filename) {
  return GetTestInputDirectory() + SB_FILE_SEP_CHAR + filename;
}

class VideoDecoderTest : public ::testing::TestWithParam<TestParam> {
 public:
  VideoDecoderTest()
      : dmp_reader_(ResolveTestFileName(GetParam().filename).c_str()) {}
  void SetUp() override {
    ASSERT_NE(dmp_reader_.video_codec(), kSbMediaVideoCodecNone);
    ASSERT_GT(dmp_reader_.number_of_video_buffers(), 0);
    ASSERT_TRUE(
        dmp_reader_.GetVideoInputBuffer(0)->video_sample_info()->is_key_frame);

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

    PlayerComponents::VideoParameters video_parameters = {
        &player_,
        dmp_reader_.video_codec(),
        kSbDrmSystemInvalid,
        &job_queue_,
        output_mode,
        fake_graphics_context_provider_.decoder_target_provider()};

    scoped_ptr<PlayerComponents> components = PlayerComponents::Create();
    components->CreateVideoComponents(video_parameters, &video_decoder_,
                                      &video_render_algorithm_,
                                      &video_renderer_sink_);
    ASSERT_TRUE(video_decoder_);

    video_decoder_->Initialize(
        std::bind(&VideoDecoderTest::OnDecoderStatusUpdate, this, _1, _2),
        std::bind(&VideoDecoderTest::OnError, this));
  }

 protected:
  enum Status {
    kNeedMoreInput = VideoDecoder::kNeedMoreInput,
    kBufferFull = VideoDecoder::kBufferFull,
    kError
  };

  struct Event {
    Status status;
    scoped_refptr<VideoFrame> frame;

    Event() : status(kNeedMoreInput) {}
    Event(Status status, scoped_refptr<VideoFrame> frame)
        : status(status), frame(frame) {}
  };

  // This function is called inside WriteMultipleInputs() whenever an event has
  // been processed.
  // |continue_process| will always be a valid pointer and always contains
  // |true| when calling this callback.  The callback can set it to false to
  // stop further processing.
  typedef std::function<void(const Event&, bool* continue_process)> EventCB;

  void WaitForNextEvent(
      Event* event,
      SbTimeMonotonic timeout = kDefaultWaitForNextEventTimeOut) {
    ASSERT_TRUE(event);

    SbTimeMonotonic start = SbTimeGetMonotonicNow();
    while (SbTimeGetMonotonicNow() - start < timeout) {
      job_queue_.RunUntilIdle();
      {
        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);
    }
    event->status = kError;
    FAIL();
  }

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

  void AssertValidDecodeTarget() {
    if (GetParam().output_mode == kSbPlayerOutputModeDecodeToTexture) {
      SbDecodeTarget decode_target = video_decoder_->GetCurrentDecodeTarget();
      ASSERT_TRUE(SbDecodeTargetIsValid(decode_target));
      fake_graphics_context_provider_.ReleaseDecodeTarget(decode_target);
    }
  }

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

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

    video_decoder_->WriteInputBuffer(input_buffer);
  }

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

  void WriteMultipleInputs(size_t start_index,
                           size_t number_of_inputs_to_write,
                           EventCB event_cb = EventCB()) {
    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 {
        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()->pts(), event.frame->pts());
        }
        decoded_frames_.push_back(event.frame);
        ASSERT_TRUE(outstanding_inputs_.find(event.frame->pts()) !=
                    outstanding_inputs_.end());
        outstanding_inputs_.erase(outstanding_inputs_.find(event.frame->pts()));
      }
      if (event_cb) {
        bool continue_process = true;
        event_cb(event, &continue_process);
        if (!continue_process) {
          return;
        }
      }
    }
  }

  void DrainOutputs(bool* error_occurred = NULL, EventCB event_cb = EventCB()) {
    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) {
        if (error_occurred) {
          *error_occurred = true;
        } else {
          FAIL();
        }
        return;
      }
      if (event.frame) {
        if (event.frame->is_end_of_stream()) {
          end_of_stream_decoded = true;
          ASSERT_TRUE(outstanding_inputs_.empty());
        } else {
          if (!decoded_frames_.empty()) {
            ASSERT_LT(decoded_frames_.back()->pts(), event.frame->pts());
          }
          decoded_frames_.push_back(event.frame);
          ASSERT_TRUE(outstanding_inputs_.find(event.frame->pts()) !=
                      outstanding_inputs_.end());
          outstanding_inputs_.erase(
              outstanding_inputs_.find(event.frame->pts()));
        }
      }
      if (event_cb) {
        bool continue_process = true;
        event_cb(event, &continue_process);
        if (!continue_process) {
          return;
        }
      }
    }
  }

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

  Mutex mutex_;
  std::deque<Event> event_queue_;

  FakeGraphicsContextProvider fake_graphics_context_provider_;
  VideoDmpReader dmp_reader_;
  scoped_ptr<VideoDecoder> video_decoder_;

  bool need_more_input_ = true;
  std::set<SbMediaTime> outstanding_inputs_;
  std::deque<scoped_refptr<VideoFrame>> decoded_frames_;

 private:
  void 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 OnError() {
    ScopedLock scoped_lock(mutex_);
    event_queue_.push_back(Event(kError, NULL));
  }

  SbPlayerPrivate player_;
  JobQueue job_queue_;
  scoped_ptr<VideoRenderAlgorithm> video_render_algorithm_;
  scoped_refptr<VideoRendererSink> video_renderer_sink_;

  bool end_of_stream_written_ = false;
};

TEST_P(VideoDecoderTest, PrerollFrameCount) {
  EXPECT_GT(video_decoder_->GetPrerollFrameCount(), 0);
}

TEST_P(VideoDecoderTest, PrerollTimeout) {
  EXPECT_GE(video_decoder_->GetPrerollTimeout(), 0);
}

// Ensure that OutputModeSupported() is callable on all combinations.
TEST_P(VideoDecoderTest, OutputModeSupported) {
  SbPlayerOutputMode kOutputModes[] = {kSbPlayerOutputModeDecodeToTexture,
                                       kSbPlayerOutputModePunchOut};
  SbMediaVideoCodec kVideoCodecs[] = {
      kSbMediaVideoCodecNone,  kSbMediaVideoCodecH264,   kSbMediaVideoCodecH265,
      kSbMediaVideoCodecMpeg2, kSbMediaVideoCodecTheora, kSbMediaVideoCodecVc1,
      kSbMediaVideoCodecVp10,  kSbMediaVideoCodecVp8,    kSbMediaVideoCodecVp9};
  for (auto output_mode : kOutputModes) {
    for (auto video_codec : kVideoCodecs) {
      VideoDecoder::OutputModeSupported(output_mode, video_codec,
                                        kSbDrmSystemInvalid);
    }
  }
}

TEST_P(VideoDecoderTest, GetCurrentDecodeTargetBeforeWriteInputBuffer) {
  if (GetParam().output_mode == kSbPlayerOutputModeDecodeToTexture) {
    SbDecodeTarget decode_target = video_decoder_->GetCurrentDecodeTarget();
    EXPECT_FALSE(SbDecodeTargetIsValid(decode_target));
    fake_graphics_context_provider_.ReleaseDecodeTarget(decode_target);
  }
}

TEST_P(VideoDecoderTest, SingleInput) {
  WriteSingleInput(0);
  WriteEndOfStream();

  bool error_occurred = false;
  ASSERT_NO_FATAL_FAILURE(DrainOutputs(
      &error_occurred, [=](const Event& event, bool* continue_process) {
        if (event.frame) {
          AssertValidDecodeTarget();
        }
        *continue_process = true;
      }));
  ASSERT_FALSE(error_occurred);
}

TEST_P(VideoDecoderTest, SingleInvalidInput) {
  need_more_input_ = false;
  auto input_buffer = dmp_reader_.GetVideoInputBuffer(0);
  outstanding_inputs_.insert(input_buffer->pts());
  std::vector<uint8_t> content(input_buffer->size(), 0xab);
  // Replace the content with invalid data.
  input_buffer->SetDecryptedContent(content.data(),
                                    static_cast<int>(content.size()));
  video_decoder_->WriteInputBuffer(input_buffer);

  WriteEndOfStream();

  bool error_occurred = true;
  ASSERT_NO_FATAL_FAILURE(DrainOutputs(&error_occurred));
  if (error_occurred) {
    ASSERT_TRUE(decoded_frames_.empty());
  } else {
    // We don't expect the video decoder to recover from a bad input but some
    // decoders may just return an empty frame.
    ASSERT_FALSE(decoded_frames_.empty());
    AssertValidDecodeTarget();
  }
}

TEST_P(VideoDecoderTest, EndOfStreamWithoutAnyInput) {
  WriteEndOfStream();
  ASSERT_NO_FATAL_FAILURE(DrainOutputs());
}

TEST_P(VideoDecoderTest, ResetBeforeInput) {
  EXPECT_FALSE(HasPendingEvents());
  ResetDecoderAndClearPendingEvents();
  EXPECT_FALSE(HasPendingEvents());

  WriteSingleInput(0);
  WriteEndOfStream();
  ASSERT_NO_FATAL_FAILURE(DrainOutputs());
}

TEST_P(VideoDecoderTest, ResetAfterInput) {
  const size_t kMaxInputToWrite = 10;
  WriteMultipleInputs(0, kMaxInputToWrite,
                      [](const Event& event, bool* continue_process) {
                        *continue_process = event.status != kBufferFull;
                      });

  ResetDecoderAndClearPendingEvents();
  EXPECT_FALSE(HasPendingEvents());
}

TEST_P(VideoDecoderTest, MultipleInputs) {
  const size_t kMaxNumberOfExpectedDecodedFrames = 5;
  const size_t number_of_expected_decoded_frames = std::min(
      kMaxNumberOfExpectedDecodedFrames, dmp_reader_.number_of_video_buffers());
  size_t frames_decoded = 0;
  ASSERT_NO_FATAL_FAILURE(WriteMultipleInputs(
      0, dmp_reader_.number_of_video_buffers(),
      [&](const Event& event, bool* continue_process) {
        SB_UNREFERENCED_PARAMETER(event);
        frames_decoded += decoded_frames_.size();
        decoded_frames_.clear();
        *continue_process = frames_decoded < number_of_expected_decoded_frames;
      }));
  if (frames_decoded < number_of_expected_decoded_frames) {
    WriteEndOfStream();
    ASSERT_NO_FATAL_FAILURE(DrainOutputs());
  }
}

TEST_P(VideoDecoderTest, Preroll) {
  SbTimeMonotonic start = SbTimeGetMonotonicNow();
  SbTime preroll_timeout = video_decoder_->GetPrerollTimeout();
  ASSERT_NO_FATAL_FAILURE(WriteMultipleInputs(
      0, dmp_reader_.number_of_video_buffers(),
      [=](const Event& event, bool* continue_process) {
        SB_UNREFERENCED_PARAMETER(event);
        if (decoded_frames_.size() >= video_decoder_->GetPrerollFrameCount()) {
          *continue_process = false;
          return;
        }
        if (SbTimeGetMonotonicNow() - start >= preroll_timeout) {
          *continue_process = false;
          return;
        }
        *continue_process = true;
        return;
      }));
}

TEST_P(VideoDecoderTest, HoldFramesUntilFull) {
  // TODO: Move the following to VideoDecoder::GetMaxNumberOfCachedFrames().
  const size_t kMaxCachedFrames = 12;
  ASSERT_NO_FATAL_FAILURE(WriteMultipleInputs(
      0, dmp_reader_.number_of_video_buffers(),
      [=](const Event& event, bool* continue_process) {
        SB_UNREFERENCED_PARAMETER(event);
        *continue_process = decoded_frames_.size() < kMaxCachedFrames;
      }));
  WriteEndOfStream();
  bool error_occurred = false;
  ASSERT_NO_FATAL_FAILURE(DrainOutputs(
      &error_occurred, [=](const Event& event, bool* continue_process) {
        SB_UNREFERENCED_PARAMETER(event);
        *continue_process = decoded_frames_.size() < kMaxCachedFrames;
      }));
  ASSERT_FALSE(error_occurred);
}

TEST_P(VideoDecoderTest, DecodeFullGOP) {
  int gop_size = 1;
  while (gop_size < dmp_reader_.number_of_video_buffers()) {
    if (dmp_reader_.GetVideoInputBuffer(gop_size)
            ->video_sample_info()
            ->is_key_frame) {
      break;
    }
    ++gop_size;
  }

  ASSERT_NO_FATAL_FAILURE(WriteMultipleInputs(
      0, gop_size, [=](const Event& event, bool* continue_process) {
        SB_UNREFERENCED_PARAMETER(event);
        while (decoded_frames_.size() >
               video_decoder_->GetPrerollFrameCount()) {
          decoded_frames_.pop_front();
        }
        *continue_process = true;
      }));
  WriteEndOfStream();
  ASSERT_NO_FATAL_FAILURE(DrainOutputs());
}

std::vector<TestParam> GetSupportedTests() {
  SbPlayerOutputMode kOutputModes[] = {kSbPlayerOutputModeDecodeToTexture,
                                       kSbPlayerOutputModePunchOut};

  const char* kFilenames[] = {"google_glass_h264_aac.dmp",
                              "google_glass_vp9_opus.dmp"};

  static std::vector<TestParam> test_params;

  if (!test_params.empty()) {
    return test_params;
  }

  for (auto filename : kFilenames) {
    VideoDmpReader dmp_reader(ResolveTestFileName(filename).c_str());
    SB_DCHECK(dmp_reader.number_of_video_buffers() > 0);

    for (auto output_mode : kOutputModes) {
      if (!VideoDecoder::OutputModeSupported(
              output_mode, dmp_reader.video_codec(), kSbDrmSystemInvalid)) {
        continue;
      }

      auto input_buffer = dmp_reader.GetVideoInputBuffer(0);
      const auto& video_sample_info = input_buffer->video_sample_info();
      if (SbMediaIsVideoSupported(
              dmp_reader.video_codec(), video_sample_info->frame_width,
              video_sample_info->frame_height, dmp_reader.video_bitrate(),
              dmp_reader.video_fps())) {
        test_params.push_back({output_mode, filename});
      }
    }
  }

  SB_DCHECK(!test_params.empty());
  return test_params;
}

INSTANTIATE_TEST_CASE_P(VideoDecoderTests,
                        VideoDecoderTest,
                        ValuesIn(GetSupportedTests()));

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