// 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 <map>
#include <set>

#include "gpu/command_buffer/service/gpu_service_test.h"
#include "gpu/command_buffer/service/gpu_tracer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_mock.h"

namespace gpu {
namespace gles2 {

using ::testing::Return;
using ::testing::NotNull;
using ::testing::AtLeast;
using ::testing::Invoke;
using ::testing::_;

class MockOutputter : public Outputter {
 public:
  MockOutputter() {}
  MOCK_METHOD4(Trace,
               void(const std::string& category, const std::string& name,
                    int64 start_time, int64 end_time));

 protected:
  ~MockOutputter() {}
};

class GlFakeQueries {
 public:
  GlFakeQueries() {}

  void Reset() {
    current_time_ = 0;
    next_query_id_ = 23;
    alloced_queries_.clear();
    query_timestamp_.clear();
  }

  void SetCurrentGLTime(GLint64 current_time) { current_time_ = current_time; }

  void GenQueriesARB(GLsizei n, GLuint* ids) {
    for (GLsizei i = 0; i < n; i++) {
      ids[i] = next_query_id_++;
      alloced_queries_.insert(ids[i]);
    }
  }

  void DeleteQueriesARB(GLsizei n, const GLuint* ids) {
    for (GLsizei i = 0; i < n; i++) {
      alloced_queries_.erase(ids[i]);
      query_timestamp_.erase(ids[i]);
    }
  }

  void GetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
    switch (pname) {
      case GL_QUERY_RESULT_AVAILABLE: {
        std::map<GLuint, GLint64>::iterator it = query_timestamp_.find(id);
        if (it != query_timestamp_.end() && it->second <= current_time_)
          *params = 1;
        else
          *params = 0;
        break;
      }
      default:
        ASSERT_TRUE(false);
    }
  }

  void QueryCounter(GLuint id, GLenum target) {
    switch (target) {
      case GL_TIMESTAMP:
        ASSERT_TRUE(alloced_queries_.find(id) != alloced_queries_.end());
        query_timestamp_[id] = current_time_;
        break;
      default:
        ASSERT_TRUE(false);
    }
  }

  void GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64* params) {
    switch (pname) {
      case GL_QUERY_RESULT:
        ASSERT_TRUE(query_timestamp_.find(id) != query_timestamp_.end());
        *params = query_timestamp_.find(id)->second;
        break;
      default:
        ASSERT_TRUE(false);
    }
  }

 protected:
  GLint64 current_time_;
  GLuint next_query_id_;
  std::set<GLuint> alloced_queries_;
  std::map<GLuint, GLint64> query_timestamp_;
};

class BaseGpuTracerTest : public GpuServiceTest {
 public:
  BaseGpuTracerTest() {}

  ///////////////////////////////////////////////////////////////////////////

  void DoTraceTest() {
    MockOutputter* outputter = new MockOutputter();
    scoped_refptr<Outputter> outputter_ref = outputter;

    SetupTimerQueryMocks();

    // Expected results
    const std::string category_name("trace_category");
    const std::string trace_name("trace_test");
    const int64 offset_time = 3231;
    const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
    const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond;
    const int64 expect_start_time =
        (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
        offset_time;
    const int64 expect_end_time =
        (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;

    // Expected Outputter::Trace call
    EXPECT_CALL(*outputter,
                Trace(category_name, trace_name,
                      expect_start_time, expect_end_time));

    scoped_refptr<GPUTrace> trace =
        new GPUTrace(outputter_ref, category_name, trace_name,
                     offset_time, GetTracerType());

    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    trace->Start(true);

    // Shouldn't be available before End() call
    gl_fake_queries_.SetCurrentGLTime(end_timestamp);
    EXPECT_FALSE(trace->IsAvailable());

    trace->End(true);

    // Shouldn't be available until the queries complete
    gl_fake_queries_.SetCurrentGLTime(end_timestamp -
                                      base::Time::kNanosecondsPerMicrosecond);
    EXPECT_FALSE(trace->IsAvailable());

    // Now it should be available
    gl_fake_queries_.SetCurrentGLTime(end_timestamp);
    EXPECT_TRUE(trace->IsAvailable());

    // Proces should output expected Trace results to MockOutputter
    trace->Process();
  }

 protected:
  void SetUp() override {
    GpuServiceTest::SetUp();
    gl_fake_queries_.Reset();
  }

  void TearDown() override {
    gl_.reset();
    gl_fake_queries_.Reset();
    GpuServiceTest::TearDown();
  }

  virtual void SetupTimerQueryMocks() {
    // Delegate query APIs used by GPUTrace to a GlFakeQueries
    EXPECT_CALL(*gl_, GenQueriesARB(_, NotNull())).Times(AtLeast(1)).WillOnce(
        Invoke(&gl_fake_queries_, &GlFakeQueries::GenQueriesARB));

    EXPECT_CALL(*gl_, GetQueryObjectiv(_, GL_QUERY_RESULT_AVAILABLE, NotNull()))
        .Times(AtLeast(2))
        .WillRepeatedly(
             Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectiv));

    EXPECT_CALL(*gl_, QueryCounter(_, GL_TIMESTAMP))
        .Times(AtLeast(2))
        .WillRepeatedly(
             Invoke(&gl_fake_queries_, &GlFakeQueries::QueryCounter));

    EXPECT_CALL(*gl_, GetQueryObjectui64v(_, GL_QUERY_RESULT, NotNull()))
        .Times(AtLeast(2))
        .WillRepeatedly(
             Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectui64v));

    EXPECT_CALL(*gl_, DeleteQueriesARB(2, NotNull()))
        .Times(AtLeast(1))
        .WillRepeatedly(
             Invoke(&gl_fake_queries_, &GlFakeQueries::DeleteQueriesARB));
  }

  virtual GpuTracerType GetTracerType() = 0;

  GlFakeQueries gl_fake_queries_;
};

class GpuARBTimerTracerTest : public BaseGpuTracerTest {
 protected:
  GpuTracerType GetTracerType() override { return kTracerTypeARBTimer; }
};

class GpuDisjointTimerTracerTest : public BaseGpuTracerTest {
 protected:
  GpuTracerType GetTracerType() override { return kTracerTypeDisjointTimer; }
};

TEST_F(GpuARBTimerTracerTest, GPUTrace) {
  // Test basic timer query functionality
  {
    DoTraceTest();
  }
}

TEST_F(GpuDisjointTimerTracerTest, GPUTrace) {
  // Test basic timer query functionality
  {
    DoTraceTest();
  }
}

}  // namespace gles2
}  // namespace gpu
