// Copyright 2013 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 <stddef.h>
#include <memory>

#include "base/bind.h"
#include "base/debug/stack_trace.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/task_environment.h"
#include "media/base/pipeline_status.h"
#include "media/base/serial_runner.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

class SerialRunnerTest : public ::testing::Test {
 public:
  SerialRunnerTest()
      : inside_start_(false), done_called_(false), done_status_(PIPELINE_OK) {}

  SerialRunnerTest(const SerialRunnerTest&) = delete;
  SerialRunnerTest& operator=(const SerialRunnerTest&) = delete;

  ~SerialRunnerTest() override = default;

  void RunSerialRunner() {
    task_environment_.GetMainThreadTaskRunner()->PostTask(
        FROM_HERE,
        base::BindOnce(&SerialRunnerTest::StartRunnerInternal,
                       base::Unretained(this), std::move(bound_fns_)));
    base::RunLoop().RunUntilIdle();
  }

  // Pushes a bound function to the queue that will run its callback with
  // |status|. called(i) returns whether the i'th bound function pushed to the
  // queue was called while running the SerialRunner.
  void PushBoundFunction(PipelineStatus status) {
    bound_fns_.Push(base::BindOnce(&SerialRunnerTest::RunBoundFunction,
                                   base::Unretained(this), status,
                                   called_.size()));
    called_.push_back(false);
  }

  void PushBoundClosure() {
    bound_fns_.Push(base::BindOnce(&SerialRunnerTest::RunBoundClosure,
                                   base::Unretained(this), called_.size()));
    called_.push_back(false);
  }

  void PushClosure() {
    bound_fns_.Push(base::BindOnce(&SerialRunnerTest::RunClosure,
                                   base::Unretained(this), called_.size()));
    called_.push_back(false);
  }

  // Push a bound function to the queue that will delete the SerialRunner,
  // which should cancel all remaining queued work.
  void PushCancellation() {
    bound_fns_.Push(base::BindOnce(&SerialRunnerTest::CancelSerialRunner,
                                   base::Unretained(this)));
  }

  // Queries final status of pushed functions and done callback. Valid only
  // after calling RunSerialRunner().
  bool called(size_t index) { return called_[index]; }
  bool done_called() { return done_called_; }
  PipelineStatus done_status() { return done_status_; }

 private:
  void RunBoundFunction(PipelineStatus status,
                        size_t index,
                        PipelineStatusCallback status_cb) {
    EXPECT_EQ(index == 0u, inside_start_)
        << "First bound function should run on same stack as "
        << "SerialRunner::Run() while all others should not\n"
        << base::debug::StackTrace().ToString();

    called_[index] = true;
    std::move(status_cb).Run(status);
  }

  void RunBoundClosure(size_t index, base::OnceClosure done_cb) {
    EXPECT_EQ(index == 0u, inside_start_)
        << "First bound function should run on same stack as "
        << "SerialRunner::Run() while all others should not\n"
        << base::debug::StackTrace().ToString();

    called_[index] = true;
    std::move(done_cb).Run();
  }

  void RunClosure(size_t index) {
    EXPECT_EQ(index == 0u, inside_start_)
        << "First bound function should run on same stack as "
        << "SerialRunner::Run() while all others should not\n"
        << base::debug::StackTrace().ToString();

    called_[index] = true;
  }

  void StartRunnerInternal(SerialRunner::Queue bound_fns) {
    inside_start_ = true;
    runner_ = SerialRunner::Run(std::move(bound_fns),
                                base::BindOnce(&SerialRunnerTest::DoneCallback,
                                               base::Unretained(this)));
    inside_start_ = false;
  }

  void DoneCallback(PipelineStatus status) {
    EXPECT_FALSE(inside_start_)
        << "Done callback should not run on same stack as SerialRunner::Run()\n"
        << base::debug::StackTrace().ToString();

    done_called_ = true;
    done_status_ = status;
  }

  void CancelSerialRunner(PipelineStatusCallback status_cb) {
    // Tasks run by |runner_| shouldn't reset it, hence we post a task to do so.
    task_environment_.GetMainThreadTaskRunner()->PostTask(
        FROM_HERE, base::BindOnce(&SerialRunnerTest::ResetSerialRunner,
                                  base::Unretained(this)));
    std::move(status_cb).Run(PIPELINE_OK);
  }

  void ResetSerialRunner() {
    runner_.reset();
  }

  base::test::SingleThreadTaskEnvironment task_environment_;
  SerialRunner::Queue bound_fns_;
  std::unique_ptr<SerialRunner> runner_;

  // Used to enforce calling stack guarantees of the API.
  bool inside_start_;

  // Tracks whether the i'th bound function was called.
  std::vector<bool> called_;

  // Tracks whether the final done callback was called + resulting status.
  bool done_called_;
  PipelineStatus done_status_;
};

TEST_F(SerialRunnerTest, Empty) {
  RunSerialRunner();

  EXPECT_TRUE(done_called());
  EXPECT_EQ(PIPELINE_OK, done_status());
}

TEST_F(SerialRunnerTest, Single) {
  PushBoundFunction(PIPELINE_OK);
  RunSerialRunner();

  EXPECT_TRUE(called(0));
  EXPECT_TRUE(done_called());
  EXPECT_EQ(PIPELINE_OK, done_status());
}

TEST_F(SerialRunnerTest, Single_Error) {
  PushBoundFunction(PIPELINE_ERROR_ABORT);
  RunSerialRunner();

  EXPECT_TRUE(called(0));
  EXPECT_TRUE(done_called());
  EXPECT_EQ(PIPELINE_ERROR_ABORT, done_status());
}

TEST_F(SerialRunnerTest, Single_Cancel) {
  PushBoundFunction(PIPELINE_OK);
  PushCancellation();
  RunSerialRunner();

  EXPECT_TRUE(called(0));
  EXPECT_FALSE(done_called());
}

TEST_F(SerialRunnerTest, Multiple) {
  PushBoundFunction(PIPELINE_OK);
  PushBoundFunction(PIPELINE_OK);
  RunSerialRunner();

  EXPECT_TRUE(called(0));
  EXPECT_TRUE(called(1));
  EXPECT_TRUE(done_called());
  EXPECT_EQ(PIPELINE_OK, done_status());
}

TEST_F(SerialRunnerTest, Multiple_Error) {
  PushBoundFunction(PIPELINE_ERROR_ABORT);
  PushBoundFunction(PIPELINE_OK);
  RunSerialRunner();

  EXPECT_TRUE(called(0));
  EXPECT_FALSE(called(1));  // A bad status cancels remaining work.
  EXPECT_TRUE(done_called());
  EXPECT_EQ(PIPELINE_ERROR_ABORT, done_status());
}

TEST_F(SerialRunnerTest, Multiple_Cancel) {
  PushBoundFunction(PIPELINE_OK);
  PushCancellation();
  PushBoundFunction(PIPELINE_OK);
  RunSerialRunner();

  EXPECT_TRUE(called(0));
  EXPECT_FALSE(called(1));
  EXPECT_FALSE(done_called());
}

TEST_F(SerialRunnerTest, BoundClosure) {
  PushBoundClosure();
  RunSerialRunner();

  EXPECT_TRUE(called(0));
  EXPECT_TRUE(done_called());
  EXPECT_EQ(PIPELINE_OK, done_status());
}

TEST_F(SerialRunnerTest, Closure) {
  PushClosure();
  RunSerialRunner();

  EXPECT_TRUE(called(0));
  EXPECT_TRUE(done_called());
  EXPECT_EQ(PIPELINE_OK, done_status());
}

}  // namespace media
