// 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 "media/mojo/common/mojo_decoder_buffer_converter.h"

#include <stdint.h>

#include <memory>

#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/test/mock_callback.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

namespace {

uint32_t kDefaultDataPipeCapacityBytes = 1024;

MATCHER_P(MatchesDecoderBuffer, buffer, "") {
  DCHECK(arg);
  return arg->MatchesForTesting(*buffer);
}

class MojoDecoderBufferConverter {
 public:
  MojoDecoderBufferConverter(
      uint32_t data_pipe_capacity_bytes = kDefaultDataPipeCapacityBytes) {
    mojo::DataPipe data_pipe(data_pipe_capacity_bytes);

    writer = std::make_unique<MojoDecoderBufferWriter>(
        std::move(data_pipe.producer_handle));
    reader = std::make_unique<MojoDecoderBufferReader>(
        std::move(data_pipe.consumer_handle));
  }

  void ConvertAndVerify(scoped_refptr<DecoderBuffer> media_buffer) {
    base::RunLoop run_loop;
    base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_cb;
    EXPECT_CALL(mock_cb, Run(MatchesDecoderBuffer(media_buffer)))
        .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));

    mojom::DecoderBufferPtr mojo_buffer =
        writer->WriteDecoderBuffer(media_buffer);
    reader->ReadDecoderBuffer(std::move(mojo_buffer), mock_cb.Get());
    run_loop.Run();
  }

  std::unique_ptr<MojoDecoderBufferWriter> writer;
  std::unique_ptr<MojoDecoderBufferReader> reader;
};

}  // namespace

TEST(MojoDecoderBufferConverterTest, ConvertDecoderBuffer_Normal) {
  base::MessageLoop message_loop;
  const uint8_t kData[] = "hello, world";
  const uint8_t kSideData[] = "sideshow bob";
  const size_t kDataSize = base::size(kData);
  const size_t kSideDataSize = base::size(kSideData);

  scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CopyFrom(
      reinterpret_cast<const uint8_t*>(&kData), kDataSize,
      reinterpret_cast<const uint8_t*>(&kSideData), kSideDataSize));
  buffer->set_timestamp(base::TimeDelta::FromMilliseconds(123));
  buffer->set_duration(base::TimeDelta::FromMilliseconds(456));
  buffer->set_discard_padding(
      DecoderBuffer::DiscardPadding(base::TimeDelta::FromMilliseconds(5),
                                    base::TimeDelta::FromMilliseconds(6)));

  MojoDecoderBufferConverter converter;
  converter.ConvertAndVerify(buffer);
}

TEST(MojoDecoderBufferConverterTest, ConvertDecoderBuffer_EOS) {
  base::MessageLoop message_loop;
  scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CreateEOSBuffer());

  MojoDecoderBufferConverter converter;
  converter.ConvertAndVerify(buffer);
}

// TODO(xhwang): Investigate whether we can get rid of zero-byte-buffer.
// See http://crbug.com/663438
TEST(MojoDecoderBufferConverterTest, ConvertDecoderBuffer_ZeroByteBuffer) {
  base::MessageLoop message_loop;
  scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(0));

  MojoDecoderBufferConverter converter;
  converter.ConvertAndVerify(buffer);
}

TEST(MojoDecoderBufferConverterTest, ConvertDecoderBuffer_KeyFrame) {
  base::MessageLoop message_loop;
  const uint8_t kData[] = "hello, world";
  const size_t kDataSize = base::size(kData);

  scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CopyFrom(
      reinterpret_cast<const uint8_t*>(&kData), kDataSize));
  buffer->set_is_key_frame(true);
  EXPECT_TRUE(buffer->is_key_frame());

  MojoDecoderBufferConverter converter;
  converter.ConvertAndVerify(buffer);
}

TEST(MojoDecoderBufferConverterTest, ConvertDecoderBuffer_EncryptedBuffer) {
  base::MessageLoop message_loop;
  const uint8_t kData[] = "hello, world";
  const size_t kDataSize = base::size(kData);
  const char kKeyId[] = "00112233445566778899aabbccddeeff";
  const char kIv[] = "0123456789abcdef";

  std::vector<SubsampleEntry> subsamples;
  subsamples.push_back(SubsampleEntry(10, 20));
  subsamples.push_back(SubsampleEntry(30, 40));
  subsamples.push_back(SubsampleEntry(50, 60));

  scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CopyFrom(
      reinterpret_cast<const uint8_t*>(&kData), kDataSize));
  buffer->set_decrypt_config(
      DecryptConfig::CreateCencConfig(kKeyId, kIv, subsamples));
  {
    MojoDecoderBufferConverter converter;
    converter.ConvertAndVerify(buffer);
  }

  // Test 'cbcs'.
  buffer->set_decrypt_config(DecryptConfig::CreateCbcsConfig(
      kKeyId, kIv, subsamples, EncryptionPattern(5, 6)));
  {
    MojoDecoderBufferConverter converter;
    converter.ConvertAndVerify(buffer);
  }

  // Test unencrypted. This is used for clear buffer in an encrypted stream.
  buffer->set_decrypt_config(nullptr);
  {
    MojoDecoderBufferConverter converter;
    converter.ConvertAndVerify(buffer);
  }
}

// This test verifies that a DecoderBuffer larger than data-pipe capacity
// can be transmitted properly.
TEST(MojoDecoderBufferConverterTest, Chunked) {
  base::MessageLoop message_loop;
  const uint8_t kData[] = "Lorem ipsum dolor sit amet, consectetur cras amet";
  const size_t kDataSize = base::size(kData);
  scoped_refptr<DecoderBuffer> buffer =
      DecoderBuffer::CopyFrom(kData, kDataSize);

  MojoDecoderBufferConverter converter(kDataSize / 3);
  converter.ConvertAndVerify(buffer);
}

// This test verifies that MojoDecoderBufferReader::ReadCB is called with a
// NULL DecoderBuffer if data pipe is closed during transmission.
TEST(MojoDecoderBufferConverterTest, WriterSidePipeError) {
  base::MessageLoop message_loop;
  const uint8_t kData[] = "Lorem ipsum dolor sit amet, consectetur cras amet";
  const size_t kDataSize = base::size(kData);
  scoped_refptr<DecoderBuffer> media_buffer =
      DecoderBuffer::CopyFrom(kData, kDataSize);

  // Verify that ReadCB is called with a NULL decoder buffer.
  base::RunLoop run_loop;
  base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_cb;
  EXPECT_CALL(mock_cb, Run(testing::IsNull()))
      .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));

  // Make data pipe with capacity smaller than decoder buffer so that only
  // partial data is written.
  MojoDecoderBufferConverter converter(kDataSize / 2);
  mojom::DecoderBufferPtr mojo_buffer =
      converter.writer->WriteDecoderBuffer(media_buffer);
  converter.reader->ReadDecoderBuffer(std::move(mojo_buffer), mock_cb.Get());

  // Before the entire data is transmitted, close the handle on writer side.
  // The reader side will get notified and report the error.
  converter.writer.reset();
  run_loop.Run();
}

// This test verifies that MojoDecoderBuffer supports concurrent writes and
// reads.
TEST(MojoDecoderBufferConverterTest, ConcurrentDecoderBuffers) {
  base::MessageLoop message_loop;
  base::RunLoop run_loop;

  // Prevent all of the buffers from fitting at once to exercise the chunking
  // logic.
  MojoDecoderBufferConverter converter(4);

  // Three buffers: normal, EOS, normal.
  const uint8_t kData[] = "Hello, world";
  const size_t kDataSize = base::size(kData);
  scoped_refptr<DecoderBuffer> media_buffer1 =
      DecoderBuffer::CopyFrom(kData, kDataSize);
  scoped_refptr<DecoderBuffer> media_buffer2(DecoderBuffer::CreateEOSBuffer());
  scoped_refptr<DecoderBuffer> media_buffer3 =
      DecoderBuffer::CopyFrom(kData, kDataSize);

  // Expect the read callbacks to be issued in the same order.
  ::testing::InSequence scoper;
  base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_cb1;
  base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_cb2;
  base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_cb3;
  EXPECT_CALL(mock_cb1, Run(MatchesDecoderBuffer(media_buffer1)));
  EXPECT_CALL(mock_cb2, Run(MatchesDecoderBuffer(media_buffer2)));
  EXPECT_CALL(mock_cb3, Run(MatchesDecoderBuffer(media_buffer3)))
      .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));

  // Write all of the buffers at once.
  mojom::DecoderBufferPtr mojo_buffer1 =
      converter.writer->WriteDecoderBuffer(media_buffer1);
  mojom::DecoderBufferPtr mojo_buffer2 =
      converter.writer->WriteDecoderBuffer(media_buffer2);
  mojom::DecoderBufferPtr mojo_buffer3 =
      converter.writer->WriteDecoderBuffer(media_buffer3);

  // Read all of the buffers at once.
  // Technically could be satisfied by ReadDecoderBuffer() blocking, but that's
  // actually a valid implementation. (Quitting the |run_loop| won't work
  // properly with that setup though.)
  converter.reader->ReadDecoderBuffer(std::move(mojo_buffer1), mock_cb1.Get());
  converter.reader->ReadDecoderBuffer(std::move(mojo_buffer2), mock_cb2.Get());
  converter.reader->ReadDecoderBuffer(std::move(mojo_buffer3), mock_cb3.Get());

  run_loop.Run();
}

TEST(MojoDecoderBufferConverterTest, FlushWithoutRead) {
  base::MessageLoop message_loop;
  base::RunLoop run_loop;

  base::MockCallback<base::OnceClosure> mock_flush_cb;
  EXPECT_CALL(mock_flush_cb, Run());

  MojoDecoderBufferConverter converter;
  converter.reader->Flush(mock_flush_cb.Get());

  run_loop.RunUntilIdle();
}

TEST(MojoDecoderBufferConverterTest, FlushAfterRead) {
  base::MessageLoop message_loop;
  base::RunLoop run_loop;

  const uint8_t kData[] = "Lorem ipsum dolor sit amet, consectetur cras amet";
  const size_t kDataSize = base::size(kData);
  scoped_refptr<DecoderBuffer> media_buffer =
      DecoderBuffer::CopyFrom(kData, kDataSize);

  MojoDecoderBufferConverter converter(kDataSize / 3);
  converter.ConvertAndVerify(media_buffer);

  base::MockCallback<base::OnceClosure> mock_flush_cb;
  EXPECT_CALL(mock_flush_cb, Run())
      .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));

  converter.reader->Flush(mock_flush_cb.Get());

  run_loop.Run();
}

TEST(MojoDecoderBufferConverterTest, FlushBeforeRead) {
  base::MessageLoop message_loop;
  base::RunLoop run_loop;

  const uint8_t kData[] = "Lorem ipsum dolor sit amet, consectetur cras amet";
  const size_t kDataSize = base::size(kData);
  scoped_refptr<DecoderBuffer> media_buffer =
      DecoderBuffer::CopyFrom(kData, kDataSize);

  MojoDecoderBufferConverter converter;

  base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_read_cb;
  base::MockCallback<base::OnceClosure> mock_flush_cb;

  ::testing::InSequence sequence;
  EXPECT_CALL(mock_flush_cb, Run());
  EXPECT_CALL(mock_read_cb, Run(MatchesDecoderBuffer(media_buffer)))
      .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));

  // Write, Flush, then Read.
  mojom::DecoderBufferPtr mojo_buffer =
      converter.writer->WriteDecoderBuffer(media_buffer);
  converter.reader->Flush(mock_flush_cb.Get());
  converter.reader->ReadDecoderBuffer(std::move(mojo_buffer),
                                      mock_read_cb.Get());
  run_loop.Run();
}

TEST(MojoDecoderBufferConverterTest, FlushBeforeChunkedRead) {
  base::MessageLoop message_loop;
  base::RunLoop run_loop;

  const uint8_t kData[] = "Lorem ipsum dolor sit amet, consectetur cras amet";
  const size_t kDataSize = base::size(kData);
  scoped_refptr<DecoderBuffer> media_buffer =
      DecoderBuffer::CopyFrom(kData, kDataSize);

  MojoDecoderBufferConverter converter(kDataSize / 3);

  base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_read_cb;
  base::MockCallback<base::OnceClosure> mock_flush_cb;

  // Read callback should be fired after reset callback.
  ::testing::InSequence sequence;
  EXPECT_CALL(mock_flush_cb, Run());
  EXPECT_CALL(mock_read_cb, Run(MatchesDecoderBuffer(media_buffer)))
      .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));

  // Write, reset, then read.
  mojom::DecoderBufferPtr mojo_buffer =
      converter.writer->WriteDecoderBuffer(media_buffer);
  converter.reader->Flush(mock_flush_cb.Get());
  converter.reader->ReadDecoderBuffer(std::move(mojo_buffer),
                                      mock_read_cb.Get());
  run_loop.Run();
}

TEST(MojoDecoderBufferConverterTest, FlushDuringChunkedRead) {
  base::MessageLoop message_loop;
  base::RunLoop run_loop;

  const uint8_t kData[] = "Lorem ipsum dolor sit amet, consectetur cras amet";
  const size_t kDataSize = base::size(kData);
  scoped_refptr<DecoderBuffer> media_buffer =
      DecoderBuffer::CopyFrom(kData, kDataSize);

  MojoDecoderBufferConverter converter(kDataSize / 3);

  base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_read_cb;
  base::MockCallback<base::OnceClosure> mock_flush_cb;

  // Flush callback should be fired after read callback.
  ::testing::InSequence sequence;
  EXPECT_CALL(mock_read_cb, Run(MatchesDecoderBuffer(media_buffer)));
  EXPECT_CALL(mock_flush_cb, Run())
      .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));

  // Write, read, then reset.
  mojom::DecoderBufferPtr mojo_buffer =
      converter.writer->WriteDecoderBuffer(media_buffer);
  converter.reader->ReadDecoderBuffer(std::move(mojo_buffer),
                                      mock_read_cb.Get());
  converter.reader->Flush(mock_flush_cb.Get());
  run_loop.Run();
}

TEST(MojoDecoderBufferConverterTest, FlushDuringConcurrentReads) {
  base::MessageLoop message_loop;
  base::RunLoop run_loop;

  // Prevent all of the buffers from fitting at once to exercise the chunking
  // logic.
  MojoDecoderBufferConverter converter(4);
  auto& writer = converter.writer;
  auto& reader = converter.reader;

  // Three buffers: normal, EOS, normal.
  const uint8_t kData[] = "Hello, world";
  const size_t kDataSize = base::size(kData);
  auto media_buffer1 = DecoderBuffer::CopyFrom(kData, kDataSize);
  auto media_buffer2 = DecoderBuffer::CreateEOSBuffer();
  auto media_buffer3 = DecoderBuffer::CopyFrom(kData, kDataSize);

  // Expect the read callbacks to be issued in the same order.
  base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_read_cb1;
  base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_read_cb2;
  base::MockCallback<MojoDecoderBufferReader::ReadCB> mock_read_cb3;
  base::MockCallback<base::OnceClosure> mock_flush_cb;

  ::testing::InSequence scoper;
  EXPECT_CALL(mock_read_cb1, Run(MatchesDecoderBuffer(media_buffer1)));
  EXPECT_CALL(mock_read_cb2, Run(MatchesDecoderBuffer(media_buffer2)));
  EXPECT_CALL(mock_read_cb3, Run(MatchesDecoderBuffer(media_buffer3)));
  EXPECT_CALL(mock_flush_cb, Run())
      .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));

  // Write all of the buffers at once.
  auto mojo_buffer1 = writer->WriteDecoderBuffer(media_buffer1);
  auto mojo_buffer2 = writer->WriteDecoderBuffer(media_buffer2);
  auto mojo_buffer3 = writer->WriteDecoderBuffer(media_buffer3);

  // Read all of the buffers at once.
  reader->ReadDecoderBuffer(std::move(mojo_buffer1), mock_read_cb1.Get());
  reader->ReadDecoderBuffer(std::move(mojo_buffer2), mock_read_cb2.Get());
  reader->ReadDecoderBuffer(std::move(mojo_buffer3), mock_read_cb3.Get());
  reader->Flush(mock_flush_cb.Get());
  // No ReadDecoderBuffer() can be called during pending reset.

  run_loop.Run();
}

}  // namespace media
