// Copyright 2021 The Pigweed Authors
//
// 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
//
//     https://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 "pw_work_queue/work_queue.h"

#include "gtest/gtest.h"
#include "pw_function/function.h"
#include "pw_log/log.h"
#include "pw_sync/thread_notification.h"
#include "pw_thread/thread.h"
#include "pw_work_queue/test_thread.h"

namespace pw::work_queue {
namespace {

TEST(WorkQueue, PingPongOneRequestType) {
  struct {
    int counter = 0;
    sync::ThreadNotification worker_ping;
  } context;

  WorkQueueWithBuffer<10> work_queue;

  // Start the worker thread.
  thread::Thread work_thread(test::WorkQueueThreadOptions(), work_queue);

  // Pick a number bigger than the circular buffer to ensure we loop around.
  const int kPingPongs = 300;

  for (int i = 0; i < kPingPongs; ++i) {
    // Ping: throw work at the queue that will increment our counter.
    work_queue
        .PushWork([&context] {
          context.counter++;
          PW_LOG_INFO("Send pong...");
          context.worker_ping.release();
        })
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly

    // Throw a distraction in the queue.
    work_queue
        .PushWork([] {
          PW_LOG_INFO(
              "I'm a random task in the work queue; nothing to see here!");
        })
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly

    // Pong: wait for the callback to notify us from the worker thread.
    context.worker_ping.acquire();
  }

  // Wait for the worker thread to terminate.
  work_queue.RequestStop();
  work_thread.join();

  EXPECT_EQ(context.counter, kPingPongs);
}

TEST(WorkQueue, PingPongTwoRequestTypesWithExtraRequests) {
  struct {
    int counter = 0;
    sync::ThreadNotification worker_ping;
  } context_a, context_b;

  WorkQueueWithBuffer<10> work_queue;

  // Start the worker thread.
  thread::Thread work_thread(test::WorkQueueThreadOptions(), work_queue);

  // Pick a number bigger than the circular buffer to ensure we loop around.
  const int kPingPongs = 300;

  // Run a bunch of work items in the queue.
  for (int i = 0; i < kPingPongs; ++i) {
    // Other requests...
    work_queue.PushWork([] { PW_LOG_INFO("Chopping onions"); })
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly

    // Ping A: throw work at the queue that will increment our counter.
    work_queue
        .PushWork([&context_a] {
          context_a.counter++;
          context_a.worker_ping.release();
        })
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly

    // Other requests...
    work_queue.PushWork([] { PW_LOG_INFO("Dicing carrots"); })
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    work_queue.PushWork([] { PW_LOG_INFO("Blanching spinach"); })
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly

    // Ping B: throw work at the queue that will increment our counter.
    work_queue
        .PushWork([&context_b] {
          context_b.counter++;
          context_b.worker_ping.release();
        })
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly

    // Other requests...
    work_queue.PushWork([] { PW_LOG_INFO("Peeling potatoes"); })
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly

    // Pong A & B: wait for the callbacks to notify us from the worker thread.
    context_a.worker_ping.acquire();
    context_b.worker_ping.acquire();
  }

  // Wait for the worker thread to terminate.
  work_queue.RequestStop();
  work_thread.join();

  EXPECT_EQ(context_a.counter, kPingPongs);
  EXPECT_EQ(context_b.counter, kPingPongs);
}

// TODO(ewout): Add unit tests for the metrics once they have been restructured.

}  // namespace
}  // namespace pw::work_queue
