// 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 "base/bind.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
#include "gpu/command_buffer/service/gpu_timing.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 {
namespace {

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

int64 g_fakeCPUTime = 0;
int64 FakeCpuTime() {
  return g_fakeCPUTime;
}

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

  MOCK_METHOD2(TraceServiceBegin,
               void(const std::string& category, const std::string& name));

  MOCK_METHOD2(TraceServiceEnd,
               void(const std::string& category, const std::string& name));

 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 SetDisjoint() { disjointed_ = true; }

  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 GetQueryObjectivARB(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:
        FAIL() << "Invalid variable passed to GetQueryObjectivARB: " << pname;
    }
  }

  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:
        FAIL() << "Invalid variable passed to QueryCounter: " << target;
    }
  }

  void GetInteger64v(GLenum pname, GLint64 * data) {
    switch (pname) {
      case GL_TIMESTAMP:
        *data = current_time_;
        break;
      default:
        FAIL() << "Invalid variable passed to GetInteger64v: " << pname;
    }
  }

  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:
        FAIL() << "Invalid variable passed to GetQueryObjectui64v: " << pname;
    }
  }

  void GetIntegerv(GLenum pname, GLint* params) {
    switch (pname) {
      case GL_GPU_DISJOINT_EXT:
        *params = static_cast<GLint>(disjointed_);
        disjointed_ = false;
        break;
      default:
        FAIL() << "Invalid variable passed to GetIntegerv: " << pname;
    }
  }

  void Finish() {
  }

  GLenum GetError() {
    return GL_NO_ERROR;
  }

 protected:
  bool disjointed_ = false;
  GLint64 current_time_ = 0;
  GLuint next_query_id_ = 0;
  std::set<GLuint> alloced_queries_;
  std::map<GLuint, GLint64> query_timestamp_;
};

class GPUTracerTester : public GPUTracer {
 public:
  explicit GPUTracerTester(gles2::GLES2Decoder* decoder)
      : GPUTracer(decoder), tracing_enabled_(0) {
    gpu_timing_.SetCpuTimeForTesting(base::Bind(&FakeCpuTime));

    // Force tracing to be dependent on our mock variable here.
    gpu_trace_srv_category = &tracing_enabled_;
    gpu_trace_dev_category = &tracing_enabled_;
  }

  ~GPUTracerTester() override {}

  void SetTracingEnabled(bool enabled) {
    tracing_enabled_ = enabled ? 1 : 0;
  }

  void SetOutputter(scoped_refptr<Outputter> outputter) {
    set_outputter_ = outputter;
  }

 protected:
  scoped_refptr<Outputter> CreateOutputter(const std::string& name) override {
    if (set_outputter_.get()) {
      return set_outputter_;
    }
    return new MockOutputter();
  }

  void PostTask() override {
    // Process synchronously.
    Process();
  }

  unsigned char tracing_enabled_;

  scoped_refptr<Outputter> set_outputter_;
};

class BaseGpuTest : public GpuServiceTest {
 public:
  explicit BaseGpuTest(GPUTiming::TimerType test_timer_type)
      : test_timer_type_(test_timer_type) {
    gpu_timing_.SetCpuTimeForTesting(base::Bind(&FakeCpuTime));
    gpu_timing_.SetTimerTypeForTesting(test_timer_type);
  }

 protected:
  void SetUp() override {
    g_fakeCPUTime = 0;
    const char* gl_version = "3.2";
    const char* extensions = "";
    if (GetTimerType() == GPUTiming::kTimerTypeDisjoint) {
      gl_version = "opengl es 3.0";
      extensions = "GL_EXT_disjoint_timer_query";
    } else if (GetTimerType() == GPUTiming::kTimerTypeARB) {
      // TODO(sievers): The tracer should not depend on ARB_occlusion_query.
      // Try merge Query APIs (core, ARB, EXT) into a single binding each.
      extensions = "GL_ARB_timer_query GL_ARB_occlusion_query";
    }
    GpuServiceTest::SetUpWithGLVersion(gl_version, extensions);
    gl_fake_queries_.Reset();

    outputter_ref_ = new MockOutputter();
  }

  void TearDown() override {
    outputter_ref_ = NULL;

    gl_fake_queries_.Reset();
    GpuServiceTest::TearDown();
  }

  void ExpectTraceQueryMocks() {
    if (GetTimerType() != GPUTiming::kTimerTypeInvalid) {
      // Delegate query APIs used by GPUTrace to a GlFakeQueries
      EXPECT_CALL(*gl_, GenQueriesARB(2, NotNull())).Times(AtLeast(1))
          .WillRepeatedly(
              Invoke(&gl_fake_queries_, &GlFakeQueries::GenQueriesARB));

      EXPECT_CALL(*gl_, GetQueryObjectivARB(_, GL_QUERY_RESULT_AVAILABLE,
                                         NotNull()))
          .WillRepeatedly(
               Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectivARB));

      if (GetTimerType() == GPUTiming::kTimerTypeDisjoint) {
        EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, _))
          .WillRepeatedly(
               Invoke(&gl_fake_queries_, &GlFakeQueries::GetInteger64v));
      }

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

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

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

  void ExpectOutputterBeginMocks(MockOutputter* outputter,
                                 const std::string& category,
                                 const std::string& name) {
    EXPECT_CALL(*outputter,
                TraceServiceBegin(category, name));
  }

  void ExpectOutputterEndMocks(MockOutputter* outputter,
                               const std::string& category,
                               const std::string& name, int64 expect_start_time,
                               int64 expect_end_time,
                               bool trace_device) {
    EXPECT_CALL(*outputter,
                TraceServiceEnd(category, name));

    if (trace_device) {
      EXPECT_CALL(*outputter,
                  TraceDevice(category, name,
                              expect_start_time, expect_end_time))
          .Times(Exactly(1));
    } else {
      EXPECT_CALL(*outputter, TraceDevice(category, name,
                                          expect_start_time, expect_end_time))
          .Times(Exactly(0));
    }
  }

  void ExpectOutputterMocks(MockOutputter* outputter,
                            const std::string& category,
                            const std::string& name, int64 expect_start_time,
                            int64 expect_end_time) {
    ExpectOutputterBeginMocks(outputter, category, name);
    ExpectOutputterEndMocks(outputter, category, name, expect_start_time,
                            expect_end_time,
                            GetTimerType() != GPUTiming::kTimerTypeInvalid);
  }

  void ExpectTracerOffsetQueryMocks() {
    // Disjoint check should only be called by kTracerTypeDisjointTimer type.
    if (GetTimerType() == GPUTiming::kTimerTypeDisjoint) {
      EXPECT_CALL(*gl_, GetIntegerv(GL_GPU_DISJOINT_EXT, _)).Times(AtLeast(1))
          .WillRepeatedly(
              Invoke(&gl_fake_queries_, &GlFakeQueries::GetIntegerv));
    } else {
      EXPECT_CALL(*gl_, GetIntegerv(GL_GPU_DISJOINT_EXT, _)).Times(Exactly(0));
    }

    if (GetTimerType() != GPUTiming::kTimerTypeARB) {
      EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, NotNull()))
          .Times(Exactly(0));
    } else {
      EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, NotNull()))
          .Times(AtMost(1))
          .WillRepeatedly(
              Invoke(&gl_fake_queries_, &GlFakeQueries::GetInteger64v));
    }
  }

  GPUTiming::TimerType GetTimerType() { return test_timer_type_; }

  GPUTiming::TimerType test_timer_type_;
  GlFakeQueries gl_fake_queries_;

  GPUTiming gpu_timing_;
  scoped_refptr<MockOutputter> outputter_ref_;
};

// Test GPUTrace calls all the correct gl calls.
class BaseGpuTraceTest : public BaseGpuTest {
 public:
  explicit BaseGpuTraceTest(GPUTiming::TimerType test_timer_type)
      : BaseGpuTest(test_timer_type) {}

  void DoTraceTest() {
    // 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;

    ExpectTraceQueryMocks();
    ExpectOutputterMocks(outputter_ref_.get(), category_name, trace_name,
                         expect_start_time, expect_end_time);

    scoped_refptr<GPUTrace> trace = new GPUTrace(
        outputter_ref_, &gpu_timing_, category_name, trace_name, true);

    gpu_timing_.SetOffsetForTesting(
        offset_time, test_timer_type_ == GPUTiming::kTimerTypeARB);

    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    g_fakeCPUTime = expect_start_time;
    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();

    outputter_ref_ = NULL;
  }
};

class GpuARBTimerTraceTest : public BaseGpuTraceTest {
 public:
  GpuARBTimerTraceTest() : BaseGpuTraceTest(GPUTiming::kTimerTypeARB) {}
};

class GpuDisjointTimerTraceTest : public BaseGpuTraceTest {
 public:
  GpuDisjointTimerTraceTest()
      : BaseGpuTraceTest(GPUTiming::kTimerTypeDisjoint) {}
};

TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTest) {
  DoTraceTest();
}

TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTest) {
  DoTraceTest();
}

// Test GPUTracer calls all the correct gl calls.
class BaseGpuTracerTest : public BaseGpuTest {
 public:
  explicit BaseGpuTracerTest(GPUTiming::TimerType test_timer_type)
      : BaseGpuTest(test_timer_type) {}

  void DoBasicTracerTest() {
    ExpectTracerOffsetQueryMocks();

    MockGLES2Decoder decoder;
    EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
    GPUTracerTester tracer(&decoder);
    tracer.SetTracingEnabled(true);

    tracer.SetOutputter(outputter_ref_);

    ASSERT_TRUE(tracer.BeginDecoding());
    ASSERT_TRUE(tracer.EndDecoding());

    outputter_ref_ = NULL;
  }

  void DoTracerMarkersTest() {
    ExpectTracerOffsetQueryMocks();

    EXPECT_CALL(*gl_, GetError()).Times(AtLeast(0))
          .WillRepeatedly(
               Invoke(&gl_fake_queries_, &GlFakeQueries::GetError));

    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;

    MockGLES2Decoder decoder;
    EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
    GPUTracerTester tracer(&decoder);
    tracer.SetTracingEnabled(true);

    tracer.SetOutputter(outputter_ref_);

    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    g_fakeCPUTime = expect_start_time;

    ASSERT_TRUE(tracer.BeginDecoding());

    ExpectTraceQueryMocks();

    // This will test multiple marker sources which overlap one another.
    for (int i = 0; i < NUM_TRACER_SOURCES; ++i) {
      // Set times so each source has a different time.
      gl_fake_queries_.SetCurrentGLTime(
          start_timestamp +
          (i * base::Time::kNanosecondsPerMicrosecond));
      g_fakeCPUTime = expect_start_time + i;

      // Each trace name should be different to differentiate.
      const char num_char = static_cast<char>('0' + i);
      std::string source_category = category_name + num_char;
      std::string source_trace_name = trace_name + num_char;

      ExpectOutputterBeginMocks(outputter_ref_.get(),
                                source_category, source_trace_name);

      const GpuTracerSource source = static_cast<GpuTracerSource>(i);
      ASSERT_TRUE(tracer.Begin(source_category, source_trace_name, source));
    }

    for (int i = 0; i < NUM_TRACER_SOURCES; ++i) {
      // Set times so each source has a different time.
      gl_fake_queries_.SetCurrentGLTime(
          end_timestamp +
          (i * base::Time::kNanosecondsPerMicrosecond));
      g_fakeCPUTime = expect_start_time + i;

      // Each trace name should be different to differentiate.
      const char num_char = static_cast<char>('0' + i);
      std::string source_category = category_name + num_char;
      std::string source_trace_name = trace_name + num_char;

      ExpectOutputterEndMocks(outputter_ref_.get(), source_category,
                              source_trace_name, expect_start_time + i,
                              expect_end_time + i,
                              GetTimerType() != GPUTiming::kTimerTypeInvalid);

      const GpuTracerSource source = static_cast<GpuTracerSource>(i);

      // Check if the current category/name are correct for this source.
      ASSERT_EQ(source_category, tracer.CurrentCategory(source));
      ASSERT_EQ(source_trace_name, tracer.CurrentName(source));

      ASSERT_TRUE(tracer.End(source));
    }

    ASSERT_TRUE(tracer.EndDecoding());

    outputter_ref_ = NULL;
  }

  void DoDisjointTest() {
    // Cause a disjoint in a middle of a trace and expect no output calls.
    ExpectTracerOffsetQueryMocks();

    EXPECT_CALL(*gl_, GetError()).Times(AtLeast(0))
          .WillRepeatedly(
               Invoke(&gl_fake_queries_, &GlFakeQueries::GetError));

    const std::string category_name("trace_category");
    const std::string trace_name("trace_test");
    const GpuTracerSource source = static_cast<GpuTracerSource>(0);
    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;

    MockGLES2Decoder decoder;
    EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
    GPUTracerTester tracer(&decoder);
    tracer.SetTracingEnabled(true);

    tracer.SetOutputter(outputter_ref_);

    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    g_fakeCPUTime = expect_start_time;

    ASSERT_TRUE(tracer.BeginDecoding());

    ExpectTraceQueryMocks();

    ExpectOutputterBeginMocks(outputter_ref_.get(),
                              category_name, trace_name);
    ASSERT_TRUE(tracer.Begin(category_name, trace_name, source));

    gl_fake_queries_.SetCurrentGLTime(end_timestamp);
    g_fakeCPUTime = expect_end_time;
    gl_fake_queries_.SetDisjoint();

    ExpectOutputterEndMocks(outputter_ref_.get(), category_name, trace_name,
                            expect_start_time, expect_end_time, false);

    ASSERT_TRUE(tracer.End(source));
    ASSERT_TRUE(tracer.EndDecoding());

    outputter_ref_ = NULL;
  }
};

class InvalidTimerTracerTest : public BaseGpuTracerTest {
 public:
  InvalidTimerTracerTest() : BaseGpuTracerTest(GPUTiming::kTimerTypeInvalid) {}
};

class GpuARBTimerTracerTest : public BaseGpuTracerTest {
 public:
  GpuARBTimerTracerTest() : BaseGpuTracerTest(GPUTiming::kTimerTypeARB) {}
};

class GpuDisjointTimerTracerTest : public BaseGpuTracerTest {
 public:
  GpuDisjointTimerTracerTest()
      : BaseGpuTracerTest(GPUTiming::kTimerTypeDisjoint) {}
};

TEST_F(InvalidTimerTracerTest, InvalidTimerBasicTracerTest) {
  DoBasicTracerTest();
}

TEST_F(GpuARBTimerTracerTest, ARBTimerBasicTracerTest) {
  DoBasicTracerTest();
}

TEST_F(GpuDisjointTimerTracerTest, DisjointTimerBasicTracerTest) {
  DoBasicTracerTest();
}

TEST_F(InvalidTimerTracerTest, InvalidTimerTracerMarkersTest) {
  DoTracerMarkersTest();
}

TEST_F(GpuARBTimerTracerTest, ARBTimerBasicTracerMarkersTest) {
  DoTracerMarkersTest();
}

TEST_F(GpuDisjointTimerTracerTest, DisjointTimerBasicTracerMarkersTest) {
  DoTracerMarkersTest();
}

TEST_F(GpuDisjointTimerTracerTest, DisjointTimerDisjointTraceTest) {
  DoDisjointTest();
}

class GPUTracerTest : public GpuServiceTest {
 protected:
  void SetUp() override {
    g_fakeCPUTime = 0;
    GpuServiceTest::SetUpWithGLVersion("3.2", "");
    decoder_.reset(new MockGLES2Decoder());
    EXPECT_CALL(*decoder_, GetGLContext())
        .Times(AtMost(1))
        .WillRepeatedly(Return(GetGLContext()));
    tracer_tester_.reset(new GPUTracerTester(decoder_.get()));
  }

  void TearDown() override {
    tracer_tester_ = nullptr;
    decoder_ = nullptr;
    GpuServiceTest::TearDown();
  }
  scoped_ptr<MockGLES2Decoder> decoder_;
  scoped_ptr<GPUTracerTester> tracer_tester_;
};

TEST_F(GPUTracerTest, IsTracingTest) {
  EXPECT_FALSE(tracer_tester_->IsTracing());
  tracer_tester_->SetTracingEnabled(true);
  EXPECT_TRUE(tracer_tester_->IsTracing());
}
// Test basic functionality of the GPUTracerTester.
TEST_F(GPUTracerTest, DecodeTest) {
  ASSERT_TRUE(tracer_tester_->BeginDecoding());
  EXPECT_FALSE(tracer_tester_->BeginDecoding());
  ASSERT_TRUE(tracer_tester_->EndDecoding());
  EXPECT_FALSE(tracer_tester_->EndDecoding());
}

TEST_F(GPUTracerTest, TraceDuringDecodeTest) {
  const std::string category_name("trace_category");
  const std::string trace_name("trace_test");

  EXPECT_FALSE(
      tracer_tester_->Begin(category_name, trace_name, kTraceGroupMarker));

  ASSERT_TRUE(tracer_tester_->BeginDecoding());
  EXPECT_TRUE(
      tracer_tester_->Begin(category_name, trace_name, kTraceGroupMarker));
  ASSERT_TRUE(tracer_tester_->EndDecoding());
}

}  // namespace
}  // namespace gles2
}  // namespace gpu
