// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "base/time.h"
#include "cobalt/render_tree/composition_node.h"
#include "cobalt/renderer/submission.h"
#include "cobalt/renderer/submission_queue.h"
#include "testing/gtest/include/gtest/gtest.h"

using cobalt::renderer::Submission;
using cobalt::renderer::SubmissionQueue;

namespace {
const int kMaxQueueSize = 4;

Submission MakeSubmissionWithUniqueRenderTree(
    const base::TimeDelta& time_offset) {
  // Create a dummy, but unique, render tree.
  cobalt::render_tree::CompositionNode::Builder builder;
  Submission submission(new cobalt::render_tree::CompositionNode(builder));
  submission.time_offset = time_offset;

  return submission;
}

Submission MakeSubmissionWithUniqueRenderTree(double time_offset_in_seconds) {
  return MakeSubmissionWithUniqueRenderTree(
      base::TimeDelta::FromSecondsD(time_offset_in_seconds));
}

base::TimeTicks SecondsToTime(double seconds) {
  return base::TimeTicks() + base::TimeDelta::FromSecondsD(seconds);
}
}  // namespace

// Simple "make sure we get the single item out what we put in" test.
TEST(SubmissionQueueTest, SimpleSubmit) {
  SubmissionQueue queue(4, base::TimeDelta::FromSeconds(1));

  // Make a submission with submission time of 1.0 seconds.
  Submission first = MakeSubmissionWithUniqueRenderTree(1.0);
  // Submit this to the queue at renderer time 2.0 seconds.
  queue.PushSubmission(first, SecondsToTime(2.0));

  // Get the current submission at the "same" time that the only queued
  // submission was pushed into it.
  Submission current = queue.GetCurrentSubmission(SecondsToTime(2.0));

  // Verify that it is the render tree we expect it to be and also that its
  // time is exactly equal to the submission's original time.
  EXPECT_EQ(first.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(1.0, current.time_offset.InSecondsF());
}

// Test that the returned current submission has a time offset that increases
// as renderer time increases.
TEST(SubmissionQueueTest, SubmissionTimeOffsetIncreases) {
  SubmissionQueue queue(4, base::TimeDelta::FromSeconds(1));

  Submission first = MakeSubmissionWithUniqueRenderTree(1.0);
  queue.PushSubmission(first, SecondsToTime(2.0));

  // Check that as we increase the renderer time, the current submission time
  // increases at the same pace.
  Submission current = queue.GetCurrentSubmission(SecondsToTime(2.0));
  EXPECT_EQ(first.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(1.0, current.time_offset.InSecondsF());

  current = queue.GetCurrentSubmission(SecondsToTime(2.5));
  EXPECT_EQ(first.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(1.5, current.time_offset.InSecondsF());

  current = queue.GetCurrentSubmission(SecondsToTime(6.0));
  EXPECT_EQ(first.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(5.0, current.time_offset.InSecondsF());
}

// This test makes sure that if we queue multiple submissions, we will see each
// of them become the current submission as time moves forward.
TEST(SubmissionQueueTest, MultipleSubmissionsBecomeCurrentAsTimeAdvances) {
  // We choose a very long time for the convergence time so that the renderer
  // time will not skew much during this test.
  SubmissionQueue queue(4, base::TimeDelta::FromSeconds(1000));

  Submission first = MakeSubmissionWithUniqueRenderTree(1.0);
  Submission second = MakeSubmissionWithUniqueRenderTree(2.0);
  Submission third = MakeSubmissionWithUniqueRenderTree(3.0);
  Submission fourth = MakeSubmissionWithUniqueRenderTree(4.0);

  queue.PushSubmission(first, SecondsToTime(2.0));
  queue.PushSubmission(second, SecondsToTime(2.1));
  queue.PushSubmission(third, SecondsToTime(2.2));
  queue.PushSubmission(fourth, SecondsToTime(2.3));

  // Check that as we increase the renderer time, the current submission time
  // increases at the same pace.
  Submission current = queue.GetCurrentSubmission(SecondsToTime(2.5));
  EXPECT_EQ(first.render_tree, current.render_tree);

  current = queue.GetCurrentSubmission(SecondsToTime(3.5));
  EXPECT_EQ(second.render_tree, current.render_tree);

  current = queue.GetCurrentSubmission(SecondsToTime(4.5));
  EXPECT_EQ(third.render_tree, current.render_tree);

  current = queue.GetCurrentSubmission(SecondsToTime(5.5));
  EXPECT_EQ(fourth.render_tree, current.render_tree);
}

TEST(SubmissionQueueTest, TimeSkewsTowardsFasterOffsets) {
  SubmissionQueue queue(4, base::TimeDelta::FromSeconds(1));

  Submission first = MakeSubmissionWithUniqueRenderTree(1.0);
  Submission second = MakeSubmissionWithUniqueRenderTree(5.0);

  // Offset of 1.0 from render tree time.
  queue.PushSubmission(first, SecondsToTime(2.0));
  // Offset of 0.5 from render tree time.
  queue.PushSubmission(second, SecondsToTime(5.5));

  // Check that the first submission has up until this point had its time
  // advanced at the same rate as the renderer.
  Submission current = queue.GetCurrentSubmission(SecondsToTime(5.5));
  EXPECT_EQ(first.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(4.5, current.time_offset.InSecondsF());

  // At this point we are half-way through the transition, where the renderer
  // moves from being offset 1.0 from the submission time to 0.5 from the
  // transition time.  At the half-way point, we should also be exactly half
  // way through the transition (assuming a cubic bezier is used), so that
  // means our offset should be 0.75 at this point, so we have moved 0.25
  // seconds forward in time.
  current = queue.GetCurrentSubmission(SecondsToTime(6.0));
  EXPECT_EQ(second.render_tree, current.render_tree);
  EXPECT_NEAR(5.25, current.time_offset.InSecondsF(), 0.001);

  // After 1 second later, we should always be at offset 0.5 from the submission
  // time.
  current = queue.GetCurrentSubmission(SecondsToTime(8.0));
  EXPECT_EQ(second.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(7.5, current.time_offset.InSecondsF());
}

TEST(SubmissionQueueTest,
     TimeDoesNotSkewTowardsFasterOffsetsWhenLatencyReductionIsDisabled) {
  SubmissionQueue queue(4, base::TimeDelta::FromSeconds(1), false);

  Submission first = MakeSubmissionWithUniqueRenderTree(1.0);
  Submission second = MakeSubmissionWithUniqueRenderTree(5.0);

  // Offset of 1.0 from render tree time.
  queue.PushSubmission(first, SecondsToTime(2.0));
  // Offset of 0.5 from render tree time.
  queue.PushSubmission(second, SecondsToTime(5.5));

  // Check that the first submission has up until this point had its time
  // advanced at the same rate as the renderer.
  Submission current = queue.GetCurrentSubmission(SecondsToTime(5.5));
  EXPECT_EQ(first.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(4.5, current.time_offset.InSecondsF());

  // At this point we are half-way through the transition.  Ordinarily the
  // submission queue would try to transition from the initial offset of 1.0
  // to the new offset of 0.5, but because latency reduction is disabled, the
  // offset should never increase and it should stay at 1.0.
  current = queue.GetCurrentSubmission(SecondsToTime(6.0));
  EXPECT_EQ(second.render_tree, current.render_tree);
  EXPECT_NEAR(5, current.time_offset.InSecondsF(), 0.001);

  // After 1 second later, we should still be unchanged from offset 1.0
  current = queue.GetCurrentSubmission(SecondsToTime(8.0));
  EXPECT_EQ(second.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(7, current.time_offset.InSecondsF());

  // A third submission that increases the latency should indeed still affect
  // the submission queue transitioned time.
  Submission third = MakeSubmissionWithUniqueRenderTree(9.5);
  queue.PushSubmission(third, SecondsToTime(11.0));

  // Nothing should have changed yet...
  current = queue.GetCurrentSubmission(SecondsToTime(11.0));
  EXPECT_EQ(third.render_tree, current.render_tree);
  EXPECT_NEAR(10, current.time_offset.InSecondsF(), 0.001);

  // We should be transitioning to a larger offset now...
  current = queue.GetCurrentSubmission(SecondsToTime(11.5));
  EXPECT_EQ(third.render_tree, current.render_tree);
  EXPECT_NEAR(10.25, current.time_offset.InSecondsF(), 0.001);
}

// Check that inserting a submission older than what the renderer thinks the
// submission time is will cause the SubmissionQueue to jump back in time to
// make to accomodate the newly pushed old submission.
TEST(SubmissionQueueTest, PushingOldTimeResetsQueue) {
  SubmissionQueue queue(4, base::TimeDelta::FromSeconds(1));

  Submission first = MakeSubmissionWithUniqueRenderTree(1.0);
  Submission second = MakeSubmissionWithUniqueRenderTree(2.0);
  Submission third = MakeSubmissionWithUniqueRenderTree(3.0);

  queue.PushSubmission(first, SecondsToTime(2.0));
  queue.PushSubmission(second, SecondsToTime(2.5));

  // Check that we're still returning the first tree at this point.
  Submission current = queue.GetCurrentSubmission(SecondsToTime(2.5));
  EXPECT_EQ(first.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(1.5, current.time_offset.InSecondsF());

  queue.PushSubmission(third, SecondsToTime(5.0));

  // We expect the submission queue to not do anything rash at this point, even
  // though it was inserted late.
  current = queue.GetCurrentSubmission(SecondsToTime(5.0));
  EXPECT_EQ(third.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(4.5, current.time_offset.InSecondsF());

  // Make sure that we never go backwards in time, even if the difference
  // between the render time and submission time is shrinking quickly.
  current = queue.GetCurrentSubmission(SecondsToTime(5.5));
  EXPECT_EQ(third.render_tree, current.render_tree);
  EXPECT_DOUBLE_EQ(4.874633, current.time_offset.InSecondsF());
}

// This tests that pushing a submission into a full queue will result in the
// oldest submission to be forcefully removed, and time artifically advanced
// up to the next oldest submission.
TEST(SubmissionQueueTest, FullQueueWillEjectOldestSubmission) {
  // Loop over this with many different values to test that numerical precision
  // does not cause any problems here.
  for (int64 i = 0; i < 1000; ++i) {
    // We choose a very long time for the convergence time so that the renderer
    // time will not skew much during this test.
    SubmissionQueue queue(4, base::TimeDelta::FromSeconds(1000));

    base::TimeDelta start_time =
        base::TimeDelta::FromMicroseconds(i * i * i * i);

    Submission first = MakeSubmissionWithUniqueRenderTree(
        base::TimeDelta::FromSeconds(1) + start_time);
    Submission second = MakeSubmissionWithUniqueRenderTree(
        base::TimeDelta::FromSeconds(2) + start_time);
    Submission third = MakeSubmissionWithUniqueRenderTree(
        base::TimeDelta::FromSeconds(3) + start_time);
    Submission fourth = MakeSubmissionWithUniqueRenderTree(
        base::TimeDelta::FromSeconds(4) + start_time);

    queue.PushSubmission(first, SecondsToTime(2.0));
    queue.PushSubmission(second, SecondsToTime(2.1));
    queue.PushSubmission(third, SecondsToTime(2.2));
    queue.PushSubmission(fourth, SecondsToTime(2.3));

    Submission current = queue.GetCurrentSubmission(SecondsToTime(2.3));
    EXPECT_EQ(first.render_tree, current.render_tree);

    // Since the queue has a maximum size of 4 submissions, pushing this 5th
    // submission should result in the first submission being ejected, and time
    // being advanced to that of the second submission.
    Submission fifth = MakeSubmissionWithUniqueRenderTree(
        base::TimeDelta::FromSeconds(5) + start_time);
    queue.PushSubmission(fifth, SecondsToTime(2.4));

    current = queue.GetCurrentSubmission(SecondsToTime(2.4));
    EXPECT_EQ(second.render_tree, current.render_tree);
    EXPECT_EQ(base::TimeDelta::FromSeconds(2) + start_time,
              current.time_offset);
  }
}
