// 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/gles2_cmd_decoder_mock.h"
#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_context_stub.h"
#include "ui/gl/gl_mock.h"
#include "ui/gl/gl_surface_stub.h"

namespace gpu {
namespace gles2 {

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

class FakeCPUTime : public CPUTime {
 public:
  FakeCPUTime()
      : current_cpu_time_(0) {
  }

  int64 GetCurrentTime() override {
    return current_cpu_time_;
  }

  void SetFakeCPUTime(int64 cpu_time) {
    current_cpu_time_ = cpu_time;
  }

 protected:
  ~FakeCPUTime() override {}

  int64 current_cpu_time_;
};

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_;
  GLint64 current_time_;
  GLuint next_query_id_;
  std::set<GLuint> alloced_queries_;
  std::map<GLuint, GLint64> query_timestamp_;
};

class GPUTracerTester : public GPUTracer {
 public:
  GPUTracerTester(GpuTracerType tracer_type, gles2::GLES2Decoder* decoder)
      : GPUTracer(decoder),
        tracing_enabled_(0),
        test_tracer_type_(tracer_type) {
    // 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;
  }

  void SetCPUTime(scoped_refptr<CPUTime> cputime) {
    set_cputime_ = cputime;
  }

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

  scoped_refptr<CPUTime> CreateCPUTime() override {
    if (set_cputime_.get()) {
      return set_cputime_;
    }
    return new FakeCPUTime();
  }

  GpuTracerType DetermineTracerType() override {
    return test_tracer_type_;
  }

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

  unsigned char tracing_enabled_;
  GpuTracerType test_tracer_type_;

  scoped_refptr<Outputter> set_outputter_;
  scoped_refptr<CPUTime> set_cputime_;
};

class BaseGpuTest : public GpuServiceTest {
 public:
  BaseGpuTest(GpuTracerType test_tracer_type)
      : test_tracer_type_(test_tracer_type) {
  }

 protected:
  void SetUp() override {
    GpuServiceTest::SetUp();
    gl_fake_queries_.Reset();
    gl_surface_ = new gfx::GLSurfaceStub();
    gl_context_ = new gfx::GLContextStub();
    gl_context_->MakeCurrent(gl_surface_.get());

    outputter_ref_ = new MockOutputter();
    cpu_time_ref_ = new FakeCPUTime;
  }

  void TearDown() override {
    outputter_ref_ = NULL;
    cpu_time_ref_ = NULL;

    gl_context_->ReleaseCurrent(gl_surface_.get());
    gl_context_ = NULL;
    gl_surface_ = NULL;

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

  void ExpectTraceQueryMocks() {
    if (GetTracerType() != kTracerTypeInvalid) {
      // 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 (GetTracerType() == kTracerTypeDisjointTimer) {
        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,
                            GetTracerType() != kTracerTypeInvalid);
  }

  void ExpectTracerOffsetQueryMocks() {
    // Disjoint check should only be called by kTracerTypeDisjointTimer type.
    if (GetTracerType() == kTracerTypeDisjointTimer) {
      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));
    }

    // Timer offset calculation should only happen for the regular timer.
    if (GetTracerType() != kTracerTypeARBTimer) {
      EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, NotNull()))
          .Times(Exactly(0));
    } else {
      EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, NotNull()))
          .Times(AtLeast(1))
          .WillRepeatedly(
              Invoke(&gl_fake_queries_, &GlFakeQueries::GetInteger64v));
    }
  }

  GpuTracerType GetTracerType() { return test_tracer_type_; }

  GpuTracerType test_tracer_type_;
  GlFakeQueries gl_fake_queries_;

  scoped_refptr<MockOutputter> outputter_ref_;
  scoped_refptr<FakeCPUTime> cpu_time_ref_;

  scoped_refptr<gfx::GLSurface> gl_surface_;
  scoped_refptr<gfx::GLContext> gl_context_;
};

// Test GPUTrace calls all the correct gl calls.
class BaseGpuTraceTest : public BaseGpuTest {
 public:
  BaseGpuTraceTest(GpuTracerType test_tracer_type)
      : BaseGpuTest(test_tracer_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_, cpu_time_ref_, category_name, trace_name,
                     offset_time, GetTracerType());

    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    cpu_time_ref_->SetFakeCPUTime(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;
    cpu_time_ref_ = NULL;
  }
};

class GpuARBTimerTraceTest : public BaseGpuTraceTest {
 public:
  GpuARBTimerTraceTest()
      : BaseGpuTraceTest(kTracerTypeARBTimer) {
  }
};

class GpuDisjointTimerTraceTest : public BaseGpuTraceTest {
 public:
  GpuDisjointTimerTraceTest()
      : BaseGpuTraceTest(kTracerTypeDisjointTimer) {
  }
};

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

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

// Test GPUTracer calls all the correct gl calls.
class BaseGpuTracerTest : public BaseGpuTest {
 public:
  BaseGpuTracerTest(GpuTracerType test_tracer_type)
      : BaseGpuTest(test_tracer_type) {
  }

  void DoBasicTracerTest() {
    ExpectTracerOffsetQueryMocks();

    MockGLES2Decoder decoder;
    GPUTracerTester tracer(test_tracer_type_, &decoder);
    tracer.SetTracingEnabled(true);

    tracer.SetOutputter(outputter_ref_);
    tracer.SetCPUTime(cpu_time_ref_);

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

    outputter_ref_ = NULL;
    cpu_time_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;
    GPUTracerTester tracer(test_tracer_type_, &decoder);
    tracer.SetTracingEnabled(true);

    tracer.SetOutputter(outputter_ref_);
    tracer.SetCPUTime(cpu_time_ref_);

    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    cpu_time_ref_->SetFakeCPUTime(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));
      cpu_time_ref_->SetFakeCPUTime(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));
      cpu_time_ref_->SetFakeCPUTime(expect_end_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,
                              GetTracerType() != kTracerTypeInvalid);

      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;
    cpu_time_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;
    GPUTracerTester tracer(test_tracer_type_, &decoder);
    tracer.SetTracingEnabled(true);

    tracer.SetOutputter(outputter_ref_);
    tracer.SetCPUTime(cpu_time_ref_);

    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    cpu_time_ref_->SetFakeCPUTime(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);
    cpu_time_ref_->SetFakeCPUTime(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;
    cpu_time_ref_ = NULL;
  }
};

class InvalidTimerTracerTest : public BaseGpuTracerTest {
 public:
  InvalidTimerTracerTest()
      : BaseGpuTracerTest(kTracerTypeInvalid) {
  }
};

class GpuARBTimerTracerTest : public BaseGpuTracerTest {
 public:
  GpuARBTimerTracerTest()
      : BaseGpuTracerTest(kTracerTypeARBTimer) {
  }
};

class GpuDisjointTimerTracerTest : public BaseGpuTracerTest {
 public:
  GpuDisjointTimerTracerTest()
      : BaseGpuTracerTest(kTracerTypeDisjointTimer) {
  }
};

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();
}

// Test basic functionality of the GPUTracerTester.
TEST(GPUTracerTester, IsTracingTest) {
  MockGLES2Decoder decoder;
  GPUTracerTester tracer_tester(kTracerTypeInvalid, &decoder);
  EXPECT_FALSE(tracer_tester.IsTracing());
  tracer_tester.SetTracingEnabled(true);
  EXPECT_TRUE(tracer_tester.IsTracing());
}

TEST(GPUTracerTester, DecodeTest) {
  MockGLES2Decoder decoder;
  GPUTracerTester tracer_tester(kTracerTypeInvalid, &decoder);
  ASSERT_TRUE(tracer_tester.BeginDecoding());
  EXPECT_FALSE(tracer_tester.BeginDecoding());
  ASSERT_TRUE(tracer_tester.EndDecoding());
  EXPECT_FALSE(tracer_tester.EndDecoding());
}

TEST(GPUTracerTester, TraceDuringDecodeTest) {
  MockGLES2Decoder decoder;
  GPUTracerTester tracer_tester(kTracerTypeInvalid, &decoder);
  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 gles2
}  // namespace gpu
