// 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_freertos/thread_iteration.h"

#include "pw_thread/thread_iteration.h"

#include <cstddef>
#include <string_view>

#include "FreeRTOS.h"
#include "pw_span/span.h"
#include "pw_status/status.h"
#include "pw_thread/thread_info.h"
#include "pw_thread_freertos/freertos_tsktcb.h"
#include "pw_thread_freertos/util.h"

namespace pw::thread {
namespace {

bool StackInfoCollector(TaskHandle_t current_thread,
                        const pw::thread::ThreadCallback& cb) {
  const tskTCB& tcb = *reinterpret_cast<tskTCB*>(current_thread);
  ThreadInfo thread_info;

  span<const std::byte> current_name =
      as_bytes(span(std::string_view(tcb.pcTaskName)));
  thread_info.set_thread_name(current_name);

  // Current thread stack bounds.
  thread_info.set_stack_low_addr(reinterpret_cast<uintptr_t>(tcb.pxStack));
#if configRECORD_STACK_HIGH_ADDRESS
  thread_info.set_stack_high_addr(
      reinterpret_cast<uintptr_t>(tcb.pxEndOfStack));
#if INCLUDE_uxTaskGetStackHighWaterMark
// Walk through the stack from start to end to measure the current peak
// using high-water marked stack data.
#if (portSTACK_GROWTH > 0)
  thread_info.set_stack_peak_addr(thread_info.stack_high_addr().value() -
                                  uxTaskGetStackHighWaterMark(current_thread));
#else
  thread_info.set_stack_peak_addr(thread_info.stack_low_addr().value() +
                                  uxTaskGetStackHighWaterMark(current_thread));
#endif  // portSTACK_GROWTH > 0
#endif  // INCLUDE_uxTaskGetStackHighWaterMark
#endif  // configRECORD_STACK_HIGH_ADDRESS

  return cb(thread_info);
}

}  // namespace

// This will disable the scheduler.
Status ForEachThread(const pw::thread::ThreadCallback& cb) {
  pw::thread::freertos::ThreadCallback adapter_cb =
      [&cb](TaskHandle_t current_thread, eTaskState) {
        return StackInfoCollector(current_thread, cb);
      };
  // Suspend scheduler.
  vTaskSuspendAll();
  Status status = pw::thread::freertos::ForEachThread(adapter_cb);
  // Resume scheduler.
  xTaskResumeAll();
  return status;
}

}  // namespace pw::thread
