// Copyright 2015 The Chromium OS 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 <brillo/streams/memory_containers.h>

#include <limits>
#include <memory>

#include <brillo/streams/mock_stream.h>
#include <brillo/streams/stream_errors.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

using testing::_;
using testing::DoAll;
using testing::InSequence;
using testing::Invoke;
using testing::Return;
using testing::WithArgs;

namespace brillo {

namespace {
class MockContiguousBuffer : public data_container::ContiguousBufferBase {
 public:
  MockContiguousBuffer() = default;

  MOCK_METHOD(bool, Resize, (size_t, ErrorPtr*), (override));
  MOCK_METHOD(size_t, GetSize, (), (const, override));
  MOCK_METHOD(bool, IsReadOnly, (), (const, override));

  MOCK_METHOD(const void*,
              GetReadOnlyBuffer,
              (size_t, ErrorPtr*),
              (const, override));
  MOCK_METHOD(void*, GetBuffer, (size_t, ErrorPtr*), (override));

  MOCK_METHOD(void,
              CopyMemoryBlock,
              (void*, const void*, size_t),
              (const, override));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockContiguousBuffer);
};
}  // anonymous namespace

class MemoryContainerTest : public testing::Test {
 public:
  inline static void* IntToPtr(int addr) {
    return reinterpret_cast<void*>(addr);
  }

  inline static const void* IntToConstPtr(int addr) {
    return reinterpret_cast<const void*>(addr);
  }

  // Dummy buffer pointer values used as external data source/destination for
  // read/write operations.
  void* const test_read_buffer_ = IntToPtr(12345);
  const void* const test_write_buffer_ = IntToConstPtr(67890);

  // Dummy buffer pointer values used for internal buffer owned by the
  // memory buffer container class.
  const void* const const_buffer_ = IntToConstPtr(123);
  void* const buffer_ = IntToPtr(456);

  MockContiguousBuffer container_;
};

TEST_F(MemoryContainerTest, Read_WithinBuffer) {
  {
    InSequence s;
    EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
    EXPECT_CALL(container_, GetReadOnlyBuffer(10, _))
        .WillOnce(Return(const_buffer_));
    EXPECT_CALL(container_,
                CopyMemoryBlock(test_read_buffer_, const_buffer_, 50))
        .Times(1);
  }
  size_t read = 0;
  ErrorPtr error;
  EXPECT_TRUE(container_.Read(test_read_buffer_, 50, 10, &read, &error));
  EXPECT_EQ(50, read);
  EXPECT_EQ(nullptr, error.get());
}

TEST_F(MemoryContainerTest, Read_PastEndOfBuffer) {
  {
    InSequence s;
    EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
    EXPECT_CALL(container_, GetReadOnlyBuffer(80, _))
        .WillOnce(Return(const_buffer_));
    EXPECT_CALL(container_,
                CopyMemoryBlock(test_read_buffer_, const_buffer_, 20))
        .Times(1);
  }
  size_t read = 0;
  EXPECT_TRUE(container_.Read(test_read_buffer_, 50, 80, &read, nullptr));
  EXPECT_EQ(20, read);
}

TEST_F(MemoryContainerTest, Read_OutsideBuffer) {
  EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
  size_t read = 0;
  EXPECT_TRUE(container_.Read(test_read_buffer_, 50, 100, &read, nullptr));
  EXPECT_EQ(0, read);
}

TEST_F(MemoryContainerTest, Read_Error) {
  auto OnReadError = [](ErrorPtr* error) {
    Error::AddTo(error, FROM_HERE, "domain", "read_error", "read error");
  };

  {
    InSequence s;
    EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
    EXPECT_CALL(container_, GetReadOnlyBuffer(0, _))
        .WillOnce(DoAll(WithArgs<1>(Invoke(OnReadError)), Return(nullptr)));
  }
  size_t read = 0;
  ErrorPtr error;
  EXPECT_FALSE(container_.Read(test_read_buffer_, 10, 0, &read, &error));
  EXPECT_EQ(0, read);
  EXPECT_NE(nullptr, error.get());
  EXPECT_EQ("domain", error->GetDomain());
  EXPECT_EQ("read_error", error->GetCode());
  EXPECT_EQ("read error", error->GetMessage());
}

TEST_F(MemoryContainerTest, Write_WithinBuffer) {
  {
    InSequence s;
    EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
    EXPECT_CALL(container_, GetBuffer(10, _)).WillOnce(Return(buffer_));
    EXPECT_CALL(container_, CopyMemoryBlock(buffer_, test_write_buffer_, 50))
        .Times(1);
  }
  size_t written = 0;
  ErrorPtr error;
  EXPECT_TRUE(container_.Write(test_write_buffer_, 50, 10, &written, &error));
  EXPECT_EQ(50, written);
  EXPECT_EQ(nullptr, error.get());
}

TEST_F(MemoryContainerTest, Write_PastEndOfBuffer) {
  {
    InSequence s;
    EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
    EXPECT_CALL(container_, Resize(130, _)).WillOnce(Return(true));
    EXPECT_CALL(container_, GetBuffer(80, _)).WillOnce(Return(buffer_));
    EXPECT_CALL(container_, CopyMemoryBlock(buffer_, test_write_buffer_, 50))
        .Times(1);
  }
  size_t written = 0;
  EXPECT_TRUE(container_.Write(test_write_buffer_, 50, 80, &written, nullptr));
  EXPECT_EQ(50, written);
}

TEST_F(MemoryContainerTest, Write_OutsideBuffer) {
  {
    InSequence s;
    EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
    EXPECT_CALL(container_, Resize(160, _)).WillOnce(Return(true));
    EXPECT_CALL(container_, GetBuffer(110, _)).WillOnce(Return(buffer_));
    EXPECT_CALL(container_, CopyMemoryBlock(buffer_, test_write_buffer_, 50))
        .Times(1);
  }
  size_t written = 0;
  EXPECT_TRUE(container_.Write(test_write_buffer_, 50, 110, &written, nullptr));
  EXPECT_EQ(50, written);
}

TEST_F(MemoryContainerTest, Write_Error_Resize) {
  auto OnWriteError = [](ErrorPtr* error) {
    Error::AddTo(error, FROM_HERE, "domain", "write_error", "resize error");
  };

  {
    InSequence s;
    EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
    EXPECT_CALL(container_, Resize(160, _))
        .WillOnce(DoAll(WithArgs<1>(Invoke(OnWriteError)), Return(false)));
  }
  size_t written = 0;
  ErrorPtr error;
  EXPECT_FALSE(container_.Write(test_write_buffer_, 50, 110, &written, &error));
  EXPECT_EQ(0, written);
  EXPECT_NE(nullptr, error.get());
  EXPECT_EQ("domain", error->GetDomain());
  EXPECT_EQ("write_error", error->GetCode());
  EXPECT_EQ("resize error", error->GetMessage());
}

TEST_F(MemoryContainerTest, Write_Error) {
  auto OnWriteError = [](ErrorPtr* error) {
    Error::AddTo(error, FROM_HERE, "domain", "write_error", "write error");
  };

  {
    InSequence s;
    EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
    EXPECT_CALL(container_, Resize(160, _)).WillOnce(Return(true));
    EXPECT_CALL(container_, GetBuffer(110, _))
        .WillOnce(DoAll(WithArgs<1>(Invoke(OnWriteError)), Return(nullptr)));
  }
  size_t written = 0;
  ErrorPtr error;
  EXPECT_FALSE(container_.Write(test_write_buffer_, 50, 110, &written, &error));
  EXPECT_EQ(0, written);
  EXPECT_NE(nullptr, error.get());
  EXPECT_EQ("domain", error->GetDomain());
  EXPECT_EQ("write_error", error->GetCode());
  EXPECT_EQ("write error", error->GetMessage());
}

}  // namespace brillo
