// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <map>
#include <sstream>

#include "base/macros.h"
#include "media/base/stream_parser.h"
#include "media/base/stream_parser_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

typedef StreamParser::TrackId TrackId;
typedef StreamParser::BufferQueue BufferQueue;

const int kEnd = -1;
const uint8_t kFakeData[] = {0xFF};
const TrackId kAudioTrackId = 0;
const TrackId kVideoTrackId = 1;
const TrackId kTextTrackIdA = 2;
const TrackId kTextTrackIdB = 3;

static bool IsAudio(scoped_refptr<StreamParserBuffer> buffer) {
  return buffer->type() == DemuxerStream::AUDIO;
}

static bool IsVideo(scoped_refptr<StreamParserBuffer> buffer) {
  return buffer->type() == DemuxerStream::VIDEO;
}

static bool IsText(scoped_refptr<StreamParserBuffer> buffer) {
  return buffer->type() == DemuxerStream::TEXT;
}

// Creates and appends a sequence of StreamParserBuffers to the provided
// |queue|. |decode_timestamps| determines the number of appended buffers and
// their sequence of decode timestamps; a |kEnd| timestamp indicates the
// end of the sequence and no buffer is appended for it. Each new buffer's
// type will be |type| with track ID set to |track_id|.
static void GenerateBuffers(const int* decode_timestamps,
                            StreamParserBuffer::Type type,
                            TrackId track_id,
                            BufferQueue* queue) {
  DCHECK(decode_timestamps);
  DCHECK(queue);
  DCHECK_NE(type, DemuxerStream::UNKNOWN);
  DCHECK_LE(type, DemuxerStream::TYPE_MAX);
  for (int i = 0; decode_timestamps[i] != kEnd; ++i) {
    scoped_refptr<StreamParserBuffer> buffer =
        StreamParserBuffer::CopyFrom(kFakeData, sizeof(kFakeData),
                                     true, type, track_id);
    buffer->SetDecodeTimestamp(
        DecodeTimestamp::FromMicroseconds(decode_timestamps[i]));
    queue->push_back(buffer);
  }
}

class StreamParserTest : public testing::Test {
 protected:
  StreamParserTest() = default;

  // Returns the number of buffers in |merged_buffers_| for which |predicate|
  // returns true.
  size_t CountMatchingMergedBuffers(
      bool (*predicate)(scoped_refptr<StreamParserBuffer> buffer)) {
    return static_cast<size_t>(std::count_if(merged_buffers_.begin(),
                                             merged_buffers_.end(), predicate));
  }

  // Appends test audio buffers in the sequence described by |decode_timestamps|
  // to |audio_buffers_|. See GenerateBuffers() for |decode_timestamps| format.
  void GenerateAudioBuffers(const int* decode_timestamps) {
    GenerateBuffers(decode_timestamps, DemuxerStream::AUDIO, kAudioTrackId,
                    &buffer_queue_map_[kAudioTrackId]);
  }

  // Appends test video buffers in the sequence described by |decode_timestamps|
  // to |video_buffers_|. See GenerateBuffers() for |decode_timestamps| format.
  void GenerateVideoBuffers(const int* decode_timestamps) {
    GenerateBuffers(decode_timestamps, DemuxerStream::VIDEO, kVideoTrackId,
                    &buffer_queue_map_[kVideoTrackId]);
  }

  // Current tests only need up to two distinct text BufferQueues. This helper
  // conditionally appends buffers to the underlying |buffer_queue_map_| keyed
  // by the respective track ID. If |decode_timestamps_{a,b}|
  // is NULL, then the corresponding BufferQueue is not changed at all.
  // Note that key collision on map insertion does not replace the previous
  // value.
  void GenerateTextBuffers(const int* decode_timestamps_a,
                           const int* decode_timestamps_b) {
    if (decode_timestamps_a) {
      GenerateBuffers(decode_timestamps_a, DemuxerStream::TEXT, kTextTrackIdA,
                      &buffer_queue_map_[kTextTrackIdA]);
    }

    if (decode_timestamps_b) {
      GenerateBuffers(decode_timestamps_b, DemuxerStream::TEXT, kTextTrackIdB,
                      &buffer_queue_map_[kTextTrackIdB]);
    }
  }

  // Returns a string that describes the sequence of buffers in
  // |merged_buffers_|. The string is a concatenation of space-delimited buffer
  // descriptors in the same sequence as |merged_buffers_|. Each descriptor is
  // the concatenation of
  // 1) a single character that describes the buffer's type(), e.g. A, V, or T
  //    for audio, video, or text, respectively
  // 2) the buffer's track_id()
  // 3) ":"
  // 4) the buffer's decode timestamp.
  // If |include_type_and_text_track| is false, then items 1, 2, and 3 are
  // not included in descriptors. This is useful when buffers with different
  // media types but the same decode timestamp are expected, and the exact
  // sequence of media types for the tying timestamps is not subject to
  // verification.
  std::string MergedBufferQueueString(bool include_type_and_text_track) {
    std::stringstream results_stream;
    for (BufferQueue::const_iterator itr = merged_buffers_.begin();
         itr != merged_buffers_.end();
         ++itr) {
      if (itr != merged_buffers_.begin())
        results_stream << " ";
      const StreamParserBuffer& buffer = *(itr->get());
      if (include_type_and_text_track) {
        switch (buffer.type()) {
          case DemuxerStream::AUDIO:
            results_stream << "A";
            break;
          case DemuxerStream::VIDEO:
            results_stream << "V";
            break;
          case DemuxerStream::TEXT:
            results_stream << "T";

            break;
          default:
            NOTREACHED();
        }
        results_stream << buffer.track_id() << ":";
      }
      results_stream << buffer.GetDecodeTimestamp().InMicroseconds();
    }

    return results_stream.str();
  }

  // Verifies that MergeBufferQueues() of the current |audio_buffers_|,
  // |video_buffers_|, |text_map_|, and |merged_buffers_| returns true and
  // results in an updated |merged_buffers_| that matches expectation. The
  // expectation, specified in |expected|, is compared to the string resulting
  // from MergedBufferQueueString() (see comments for that method) with
  // |verify_type_and_text_track_sequence| passed. |merged_buffers_| is appended
  // to by the merge, and may be setup by the caller to have some pre-existing
  // buffers; it is both an input and output of this method.
  // Regardless of |verify_type_and_text_track_sequence|, the marginal number
  // of buffers of each type (audio, video, text) resulting from the merge is
  // also verified to match the number of buffers in |audio_buffers_|,
  // |video_buffers_|, and |text_map_|, respectively.
  void VerifyMergeSuccess(const std::string& expected,
                          bool verify_type_and_text_track_sequence) {
    // |merged_buffers| may already have some buffers. Count them by type for
    // later inclusion in verification.
    size_t original_audio_in_merged = CountMatchingMergedBuffers(IsAudio);
    size_t original_video_in_merged = CountMatchingMergedBuffers(IsVideo);
    size_t original_text_in_merged = CountMatchingMergedBuffers(IsText);

    EXPECT_TRUE(MergeBufferQueues(buffer_queue_map_, &merged_buffers_));

    // Verify resulting contents of |merged_buffers| matches |expected|.
    EXPECT_EQ(expected,
              MergedBufferQueueString(verify_type_and_text_track_sequence));

    // Verify that the correct number of each type of buffer is in the merge
    // result.
    size_t audio_in_merged = CountMatchingMergedBuffers(IsAudio);
    size_t video_in_merged = CountMatchingMergedBuffers(IsVideo);
    size_t text_in_merged = CountMatchingMergedBuffers(IsText);

    EXPECT_GE(audio_in_merged, original_audio_in_merged);
    EXPECT_GE(video_in_merged, original_video_in_merged);
    EXPECT_GE(text_in_merged, original_text_in_merged);

    EXPECT_EQ(buffer_queue_map_[kAudioTrackId].size(),
              audio_in_merged - original_audio_in_merged);
    if (buffer_queue_map_[kAudioTrackId].empty())
      buffer_queue_map_.erase(kAudioTrackId);
    EXPECT_EQ(buffer_queue_map_[kVideoTrackId].size(),
              video_in_merged - original_video_in_merged);
    if (buffer_queue_map_[kVideoTrackId].empty())
      buffer_queue_map_.erase(kVideoTrackId);

    size_t expected_text_buffer_count = 0;
    expected_text_buffer_count += buffer_queue_map_[kTextTrackIdA].size();
    if (buffer_queue_map_[kTextTrackIdA].empty())
      buffer_queue_map_.erase(kTextTrackIdA);
    expected_text_buffer_count += buffer_queue_map_[kTextTrackIdB].size();
    if (buffer_queue_map_[kTextTrackIdB].empty())
      buffer_queue_map_.erase(kTextTrackIdB);
    EXPECT_EQ(expected_text_buffer_count,
              text_in_merged - original_text_in_merged);
  }

  // Verifies that MergeBufferQueues() of the current |buffer_queue_map_| and
  // |merged_buffers_| returns false.
  void VerifyMergeFailure() {
    EXPECT_FALSE(MergeBufferQueues(buffer_queue_map_, &merged_buffers_));
  }

  // Helper to allow tests to clear all the input BufferQueues (except
  // |merged_buffers_|) and the BufferQueueMap that are used in
  // VerifyMerge{Success/Failure}().
  void ClearBufferQueuesButKeepAnyMergedBuffers() { buffer_queue_map_.clear(); }

 private:
  StreamParser::BufferQueueMap buffer_queue_map_;
  BufferQueue merged_buffers_;

  DISALLOW_COPY_AND_ASSIGN(StreamParserTest);
};

TEST_F(StreamParserTest, MergeBufferQueues_AllEmpty) {
  std::string expected = "";
  VerifyMergeSuccess(expected, true);
}

TEST_F(StreamParserTest, MergeBufferQueues_SingleAudioBuffer) {
  std::string expected = "A0:100";
  int audio_timestamps[] = { 100, kEnd };
  GenerateAudioBuffers(audio_timestamps);
  VerifyMergeSuccess(expected, true);
}

TEST_F(StreamParserTest, MergeBufferQueues_SingleVideoBuffer) {
  std::string expected = "V1:100";
  int video_timestamps[] = { 100, kEnd };
  GenerateVideoBuffers(video_timestamps);
  VerifyMergeSuccess(expected, true);
}

TEST_F(StreamParserTest, MergeBufferQueues_SingleTextBuffer) {
  std::string expected = "T2:100";
  int text_timestamps[] = { 100, kEnd };
  GenerateTextBuffers(text_timestamps, NULL);
  VerifyMergeSuccess(expected, true);
}

TEST_F(StreamParserTest, MergeBufferQueues_OverlappingAudioVideo) {
  std::string expected = "A0:100 V1:101 V1:102 A0:103 A0:104 V1:105";
  int audio_timestamps[] = { 100, 103, 104, kEnd };
  GenerateAudioBuffers(audio_timestamps);
  int video_timestamps[] = { 101, 102, 105, kEnd };
  GenerateVideoBuffers(video_timestamps);
  VerifyMergeSuccess(expected, true);
}

TEST_F(StreamParserTest, MergeBufferQueues_OverlappingMultipleText) {
  std::string expected = "T2:100 T2:101 T3:103 T2:104 T3:105 T3:106";
  int text_timestamps_a[] = { 100, 101, 104, kEnd };
  int text_timestamps_b[] = { 103, 105, 106, kEnd };
  GenerateTextBuffers(text_timestamps_a, text_timestamps_b);
  VerifyMergeSuccess(expected, true);
}

TEST_F(StreamParserTest, MergeBufferQueues_OverlappingAudioVideoText) {
  std::string expected = "A0:100 V1:101 T2:102 V1:103 T3:104 A0:105 V1:106 "
                         "T2:107";
  int audio_timestamps[] = { 100, 105, kEnd };
  GenerateAudioBuffers(audio_timestamps);
  int video_timestamps[] = { 101, 103, 106, kEnd };
  GenerateVideoBuffers(video_timestamps);
  int text_timestamps_a[] = { 102, 107, kEnd };
  int text_timestamps_b[] = { 104, kEnd };
  GenerateTextBuffers(text_timestamps_a, text_timestamps_b);
  VerifyMergeSuccess(expected, true);
}

TEST_F(StreamParserTest, MergeBufferQueues_NonDecreasingNoCrossMediaDuplicate) {
  std::string expected = "A0:100 A0:100 A0:100 V1:101 V1:101 V1:101 A0:102 "
                         "V1:103 V1:103";
  int audio_timestamps[] = { 100, 100, 100, 102, kEnd };
  GenerateAudioBuffers(audio_timestamps);
  int video_timestamps[] = { 101, 101, 101, 103, 103, kEnd };
  GenerateVideoBuffers(video_timestamps);
  VerifyMergeSuccess(expected, true);
}

TEST_F(StreamParserTest, MergeBufferQueues_CrossStreamDuplicates) {
  // Interface keeps the choice undefined of which stream's buffer wins the
  // selection when timestamps are tied. Verify at least the right number of
  // each kind of buffer results, and that buffers are in nondecreasing order.
  std::string expected = "100 100 100 100 100 100 102 102 102 102 102 102 102";
  int audio_timestamps[] = { 100, 100, 100, 102, kEnd };
  GenerateAudioBuffers(audio_timestamps);
  int video_timestamps[] = { 100, 100, 102, 102, 102, kEnd };
  GenerateVideoBuffers(video_timestamps);
  int text_timestamps[] = { 100, 102, 102, 102, kEnd };
  GenerateTextBuffers(text_timestamps, NULL);
  VerifyMergeSuccess(expected, false);
}

TEST_F(StreamParserTest, MergeBufferQueues_InvalidDecreasingSingleStream) {
  int audio_timestamps[] = { 101, 102, 100, 103, kEnd };
  GenerateAudioBuffers(audio_timestamps);
  VerifyMergeFailure();
}

TEST_F(StreamParserTest, MergeBufferQueues_InvalidDecreasingMultipleStreams) {
  int audio_timestamps[] = { 101, 102, 100, 103, kEnd };
  GenerateAudioBuffers(audio_timestamps);
  int video_timestamps[] = { 104, 100, kEnd };
  GenerateVideoBuffers(video_timestamps);
  VerifyMergeFailure();
}

TEST_F(StreamParserTest, MergeBufferQueues_ValidAppendToExistingMerge) {
  std::string expected = "A0:100 V1:101 T2:102 V1:103 T3:104 A0:105 V1:106 "
                         "T2:107";
  int audio_timestamps[] = { 100, 105, kEnd };
  GenerateAudioBuffers(audio_timestamps);
  int video_timestamps[] = { 101, 103, 106, kEnd };
  GenerateVideoBuffers(video_timestamps);
  int text_timestamps_a[] = { 102, 107, kEnd };
  int text_timestamps_b[] = { 104, kEnd };
  GenerateTextBuffers(text_timestamps_a, text_timestamps_b);
  VerifyMergeSuccess(expected, true);

  ClearBufferQueuesButKeepAnyMergedBuffers();

  expected = "A0:100 V1:101 T2:102 V1:103 T3:104 A0:105 V1:106 T2:107 "
             "A0:107 V1:111 T2:112 V1:113 T3:114 A0:115 V1:116 T2:117";
  int more_audio_timestamps[] = { 107, 115, kEnd };
  GenerateAudioBuffers(more_audio_timestamps);
  int more_video_timestamps[] = { 111, 113, 116, kEnd };
  GenerateVideoBuffers(more_video_timestamps);
  int more_text_timestamps_a[] = { 112, 117, kEnd };
  int more_text_timestamps_b[] = { 114, kEnd };
  GenerateTextBuffers(more_text_timestamps_a, more_text_timestamps_b);
  VerifyMergeSuccess(expected, true);
}

TEST_F(StreamParserTest, MergeBufferQueues_InvalidAppendToExistingMerge) {
  std::string expected = "A0:100 V1:101 T2:102 V1:103 T3:104 A0:105 V1:106 "
                         "T2:107";
  int audio_timestamps[] = { 100, 105, kEnd };
  GenerateAudioBuffers(audio_timestamps);
  int video_timestamps[] = { 101, 103, 106, kEnd };
  GenerateVideoBuffers(video_timestamps);
  int text_timestamps_a[] = { 102, 107, kEnd };
  int text_timestamps_b[] = { 104, kEnd };
  GenerateTextBuffers(text_timestamps_a, text_timestamps_b);
  VerifyMergeSuccess(expected, true);

  // Appending empty buffers to pre-existing merge result should succeed and not
  // change the existing result.
  ClearBufferQueuesButKeepAnyMergedBuffers();
  VerifyMergeSuccess(expected, true);

  // But appending something with a lower timestamp than the last timestamp
  // in the pre-existing merge result should fail.
  int more_audio_timestamps[] = { 106, kEnd };
  GenerateAudioBuffers(more_audio_timestamps);
  VerifyMergeFailure();
}

}  // namespace media
