// 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 "FreeRTOS.h"
#include "pw_bytes/span.h"
#include "pw_span/span.h"
#include "pw_string/string_builder.h"
#include "pw_string/util.h"
#include "pw_sync/thread_notification.h"
#include "pw_thread/non_portable_test_thread_options.h"
#include "pw_thread/thread.h"
#include "pw_thread/thread_info.h"
#include "pw_thread_freertos/freertos_tsktcb.h"
#include "pw_thread_freertos_private/thread_iteration.h"
#include "pw_unit_test/framework.h"

namespace pw::thread::freertos {
namespace {

// 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) {
  struct {
    sync::ThreadNotification start;
    sync::ThreadNotification end;
  } notify;

  const auto& options = *static_cast<const pw::thread::freertos::Options*>(
      &thread::test::TestOptionsThread0());

  thread::Thread t(options, [&notify]() {
    // Release start lock to allow test thread to continue execution.
    notify.start.release();
    while (true) {
      // Return only when end lock released by test thread.
      if (notify.end.try_acquire()) {
        return;
      }
    }
  });

  // Blocked until thread t releases start lock.
  notify.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.
  notify.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);
}

#if INCLUDE_uxTaskGetStackHighWaterMark
#if configRECORD_STACK_HIGH_ADDRESS

TEST(ThreadIteration, StackInfoCollector_PeakStackUsage) {
  // This is the value FreeRTOS expects, but it's worth noting that there's no
  // easy way to get this value directly from FreeRTOS.
  constexpr uint8_t tskSTACK_FILL_BYTE = 0xa5U;
  std::array<StackType_t, 128> stack;
  ByteSpan stack_bytes(as_writable_bytes(span(stack)));
  std::memset(stack_bytes.data(), tskSTACK_FILL_BYTE, stack_bytes.size_bytes());

  tskTCB fake_tcb;
  StringBuilder sb(fake_tcb.pcTaskName);
  sb.append("FakeTCB");
  fake_tcb.pxStack = stack.data();
  fake_tcb.pxEndOfStack = stack.data() + stack.size();

  // Clobber bytes as if they were used.
  constexpr size_t kBytesRemaining = 96;
#if portSTACK_GROWTH > 0
  std::memset(stack_bytes.data(),
              tskSTACK_FILL_BYTE ^ 0x2b,
              stack_bytes.size() - kBytesRemaining);
#else
  std::memset(&stack_bytes[kBytesRemaining],
              tskSTACK_FILL_BYTE ^ 0x2b,
              stack_bytes.size() - kBytesRemaining);
#endif  // portSTACK_GROWTH > 0

  ThreadCallback cb = [kBytesRemaining](const ThreadInfo& info) -> bool {
    EXPECT_TRUE(info.stack_high_addr().has_value());
    EXPECT_TRUE(info.stack_low_addr().has_value());
    EXPECT_TRUE(info.stack_peak_addr().has_value());

#if portSTACK_GROWTH > 0
    EXPECT_EQ(info.stack_high_addr().value() - info.stack_peak_addr().value(),
              kBytesRemaining);
#else
    EXPECT_EQ(info.stack_peak_addr().value() - info.stack_low_addr().value(),
              kBytesRemaining);
#endif  // portSTACK_GROWTH > 0
    return true;
  };

  EXPECT_TRUE(
      StackInfoCollector(reinterpret_cast<TaskHandle_t>(&fake_tcb), cb));
}

#endif  // INCLUDE_uxTaskGetStackHighWaterMark
#endif  // configRECORD_STACK_HIGH_ADDRESS

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