// Copyright (c) 2012 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 "base/bind.h"
#include "base/bind_helpers.h"
#include "base/threading/thread.h"
#include "gpu/command_buffer/common/cmd_buffer_common.h"
#include "gpu/command_buffer/service/command_buffer_service.h"
#include "gpu/command_buffer/service/transfer_buffer_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gmock/include/gmock/gmock.h"

using base::SharedMemory;
using testing::_;
using testing::DoAll;
using testing::Return;
using testing::SetArgumentPointee;
using testing::StrictMock;

namespace gpu {

class CommandBufferServiceTest : public testing::Test {
 protected:
  virtual void SetUp() {
    {
      TransferBufferManager* manager = new TransferBufferManager();
      transfer_buffer_manager_.reset(manager);
      EXPECT_TRUE(manager->Initialize());
    }
    command_buffer_.reset(
        new CommandBufferService(transfer_buffer_manager_.get()));
    EXPECT_TRUE(command_buffer_->Initialize());
  }

  int32 GetGetOffset() {
    return command_buffer_->GetLastState().get_offset;
  }

  int32 GetPutOffset() {
    return command_buffer_->GetLastState().put_offset;
  }

  int32 GetToken() {
    return command_buffer_->GetLastState().token;
  }

  int32 GetError() {
    return command_buffer_->GetLastState().error;
  }

  bool Initialize(size_t size) {
    int32 id;
    command_buffer_->CreateTransferBuffer(size, &id);
    EXPECT_GT(id, 0);
    command_buffer_->SetGetBuffer(id);
    return true;
  }

  scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
  scoped_ptr<CommandBufferService> command_buffer_;
};

TEST_F(CommandBufferServiceTest, InitializesCommandBuffer) {
  EXPECT_TRUE(Initialize(1024));
  CommandBuffer::State state = command_buffer_->GetLastState();
  EXPECT_EQ(0, state.get_offset);
  EXPECT_EQ(0, state.put_offset);
  EXPECT_EQ(0, state.token);
  EXPECT_EQ(error::kNoError, state.error);
}

namespace {

class CallbackTest {
 public:
  virtual void PutOffsetChanged() = 0;
  virtual bool GetBufferChanged(int32 id) = 0;
};

class MockCallbackTest : public CallbackTest {
 public:
   MOCK_METHOD0(PutOffsetChanged, void());
   MOCK_METHOD1(GetBufferChanged, bool(int32));
};

}  // anonymous namespace

TEST_F(CommandBufferServiceTest, CanSyncGetAndPutOffset) {
  Initialize(1024);

  scoped_ptr<StrictMock<MockCallbackTest> > change_callback(
      new StrictMock<MockCallbackTest>);
  command_buffer_->SetPutOffsetChangeCallback(
      base::Bind(
          &CallbackTest::PutOffsetChanged,
          base::Unretained(change_callback.get())));

  EXPECT_CALL(*change_callback, PutOffsetChanged());
  command_buffer_->Flush(2);
  EXPECT_EQ(0, GetGetOffset());
  EXPECT_EQ(2, GetPutOffset());

  EXPECT_CALL(*change_callback, PutOffsetChanged());
  command_buffer_->Flush(4);
  EXPECT_EQ(0, GetGetOffset());
  EXPECT_EQ(4, GetPutOffset());

  command_buffer_->SetGetOffset(2);
  EXPECT_EQ(2, GetGetOffset());
  EXPECT_CALL(*change_callback, PutOffsetChanged());
  command_buffer_->Flush(6);

  command_buffer_->Flush(-1);
  EXPECT_NE(error::kNoError, GetError());
  command_buffer_->Flush(1024);
  EXPECT_NE(error::kNoError, GetError());
}

TEST_F(CommandBufferServiceTest, SetGetBuffer) {
  int32 ring_buffer_id;
  command_buffer_->CreateTransferBuffer(1024, &ring_buffer_id);
  EXPECT_GT(ring_buffer_id, 0);

  scoped_ptr<StrictMock<MockCallbackTest> > change_callback(
      new StrictMock<MockCallbackTest>);
  command_buffer_->SetGetBufferChangeCallback(
      base::Bind(
          &CallbackTest::GetBufferChanged,
          base::Unretained(change_callback.get())));

  EXPECT_CALL(*change_callback, GetBufferChanged(ring_buffer_id))
      .WillOnce(Return(true));

  command_buffer_->SetGetBuffer(ring_buffer_id);
  EXPECT_EQ(0, GetGetOffset());
}

TEST_F(CommandBufferServiceTest, DefaultTokenIsZero) {
  EXPECT_EQ(0, GetToken());
}

TEST_F(CommandBufferServiceTest, CanSetToken) {
  command_buffer_->SetToken(7);
  EXPECT_EQ(7, GetToken());
}

TEST_F(CommandBufferServiceTest, DefaultParseErrorIsNoError) {
  EXPECT_EQ(0, GetError());
}

TEST_F(CommandBufferServiceTest, CanSetParseError) {
  command_buffer_->SetParseError(error::kInvalidSize);
  EXPECT_EQ(1, GetError());
}
}  // namespace gpu
