// 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 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;
  };

  ASSERT_EQ(OkStatus(), 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
