// Copyright 2022 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_thread/thread_iteration.h"

#include <cstddef>
#include <string_view>

#include "gtest/gtest.h"
#include "pw_span/span.h"
#include "pw_string/util.h"
#include "pw_sync/thread_notification.h"
#include "pw_thread/test_threads.h"
#include "pw_thread/thread.h"
#include "pw_thread/thread_info.h"

namespace pw::thread::freertos {
namespace {

sync::ThreadNotification lock_start;
sync::ThreadNotification lock_end;

void ForkedThreadEntry(void*) {
  // Release start lock to allow test thread to continue execution.
  lock_start.release();
  while (true) {
    // Return only when end lock released by test thread.
    if (lock_end.try_acquire()) {
      return;
    }
  }
}

// Tests thread iteration API by:
//  - Forking a test thread.
//  - Using iteration API to iterate over all running threads.
//  - Compares name of forked thread and current thread.
//  - Confirms thread exists and is iterated over.
TEST(ThreadIteration, ForkOneThread) {
  const auto& options = *static_cast<const pw::thread::freertos::Options*>(
      &thread::test::TestOptionsThread0());
  thread::Thread t(options, ForkedThreadEntry);

  // Blocked until thread t releases start lock.
  lock_start.acquire();

  struct {
    bool thread_exists;
    span<const std::byte> name;
  } temp_struct;

  temp_struct.thread_exists = false;
  // Max permissible length of task name including null byte.
  static constexpr size_t buffer_size = configMAX_TASK_NAME_LEN;

  std::string_view string(string::ClampedCString(options.name(), buffer_size));
  temp_struct.name = as_bytes(span(string));

  // Callback that confirms forked thread is checked by the iterator.
  auto cb = [&temp_struct](const ThreadInfo& thread_info) {
    // Compare sizes accounting for null byte.
    if (thread_info.thread_name().has_value()) {
      for (size_t i = 0; i < thread_info.thread_name().value().size(); i++) {
        // Compare character by character of span.
        if ((unsigned char)thread_info.thread_name().value().data()[i] !=
            (unsigned char)temp_struct.name.data()[i]) {
          return true;
        }
      }
      temp_struct.thread_exists = true;
    }
    // Signal to stop iteration.
    return false;
  };

  thread::ForEachThread(cb);

  // Signal to forked thread that execution is complete.
  lock_end.release();

  // Clean up the test thread context.
#if PW_THREAD_JOINING_ENABLED
  t.join();
#else
  t.detach();
  thread::test::WaitUntilDetachedThreadsCleanedUp();
#endif  // PW_THREAD_JOINING_ENABLED

  EXPECT_TRUE(temp_struct.thread_exists);
}

}  // namespace
}  // namespace pw::thread::freertos
