// 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.

#define PW_LOG_LEVEL PW_THREAD_EMBOS_CONFIG_LOG_LEVEL

#include "pw_thread_embos/snapshot.h"

#include <string_view>

#include "RTOS.h"
#include "pw_function/function.h"
#include "pw_log/log.h"
#include "pw_protobuf/encoder.h"
#include "pw_status/status.h"
#include "pw_thread/snapshot.h"
#include "pw_thread_embos/config.h"
#include "pw_thread_embos/util.h"
#include "pw_thread_protos/thread.pwpb.h"

namespace pw::thread::embos {
namespace {

// TODO(amontanez): This might make unit testing codepaths that use this more
// challenging.
inline bool ThreadIsRunning(const OS_TASK& thread) {
  return OS_GetpCurrentTask() == &thread;
}

void CaptureThreadState(const OS_TASK& thread, Thread::StreamEncoder& encoder) {
  if (ThreadIsRunning(thread)) {
    PW_LOG_DEBUG("Thread state: RUNNING");
    encoder.WriteState(ThreadState::Enum::RUNNING);
    return;
  }

  // One byte is reserved for task status.
  //   - The lowest two bits are for a suspend counter.
  //   - The third-lowest bit is reserved for a "timeout." (ignored here)
  //   - The highest five bits indicate what the task is blocked on if non-zero.
  //
  // Note: embOS thread state is not part of the public API. This may not be
  // correct for all versions. This has been tested on embOS 4.22, and was
  // initially reported for embOS 5.06.
  //
  // Description of how `OS_TASK::Stat` is used by embOS:
  //   https://forum.segger.com/index.php/Thread/6548-ABANDONED-Task-state-values/?postID=23963#post23963
#if OS_VERSION_GENERIC < 42200 || OS_VERSION_GENERIC > 50600
#warning embOS thread state interpretation logic is not verfied as working on this version of embOS
#endif  // OS_VERSION_GENERIC < 42200 || OS_VERSION_GENERIC > 50600

  if ((thread.Stat & 0x3) != 0) {
    PW_LOG_DEBUG("Thread state: SUSPENDED");
    encoder.WriteState(ThreadState::Enum::SUSPENDED);
  } else if ((thread.Stat & 0xf8) == 0) {
    PW_LOG_DEBUG("Thread state: READY");
    encoder.WriteState(ThreadState::Enum::READY);
  } else {
    PW_LOG_DEBUG("Thread state: BLOCKED");
    encoder.WriteState(ThreadState::Enum::BLOCKED);
  }
}

}  // namespace

Status SnapshotThreads(void* running_thread_stack_pointer,
                       SnapshotThreadInfo::StreamEncoder& encoder,
                       ProcessThreadStackCallback& stack_dumper) {
  struct {
    void* running_thread_stack_pointer;
    SnapshotThreadInfo::StreamEncoder* encoder;
    ProcessThreadStackCallback* stack_dumper;
    Status thread_capture_status;
  } ctx;
  ctx.running_thread_stack_pointer = running_thread_stack_pointer;
  ctx.encoder = &encoder;
  ctx.stack_dumper = &stack_dumper;

  ThreadCallback thread_capture_cb([&ctx](const OS_TASK& thread) -> bool {
    Thread::StreamEncoder thread_encoder = ctx.encoder->GetThreadsEncoder();
    ctx.thread_capture_status.Update(
        SnapshotThread(thread,
                       ctx.running_thread_stack_pointer,
                       thread_encoder,
                       *ctx.stack_dumper));
    // Always iterate all threads.
    return true;
  });

  if (Status status = ForEachThread(thread_capture_cb);
      !status.ok() && !status.IsFailedPrecondition()) {
    PW_LOG_ERROR("Failed to iterate threads during snapshot capture: %d",
                 static_cast<int>(status.code()));
  }

  return ctx.thread_capture_status;
}

Status SnapshotThread(const OS_TASK& thread,
                      void* running_thread_stack_pointer,
                      Thread::StreamEncoder& encoder,
                      ProcessThreadStackCallback& thread_stack_callback) {
#if OS_TRACKNAME
  PW_LOG_DEBUG("Capturing thread info for %s", thread.Name);
  encoder.WriteName(std::as_bytes(std::span(std::string_view(thread.Name))));
#else
  PW_LOG_DEBUG("Capturing thread info for thread at 0x%08x", &thread);
#endif  // OS_TRACKNAME

  CaptureThreadState(thread, encoder);

#if OS_CHECKSTACK || OS_SUPPORT_MPU
  const StackContext thread_ctx = {
      .thread_name = thread.Name,

      .stack_low_addr = reinterpret_cast<uintptr_t>(thread.pStackBot),

      .stack_high_addr =
          reinterpret_cast<uintptr_t>(thread.pStackBot) + thread.StackSize,

      // If the thread is active, the stack pointer in the TCB is stale.
      .stack_pointer = reinterpret_cast<uintptr_t>(
          ThreadIsRunning(thread) ? running_thread_stack_pointer
                                  : thread.pStack),
      .stack_pointer_est_peak = reinterpret_cast<uintptr_t>(thread.pStackBot) +
                                thread.StackSize - OS_GetStackUsed(&thread),
  };

  return SnapshotStack(thread_ctx, encoder, thread_stack_callback);
#else
  PW_LOG_DEBUG("Stack pointer: 0x%08x", running_thread_stack_pointer);
  encoder.WriteStackPointer(reinterpret_cast<uintptr_t>(
      ThreadIsRunning(thread) ? running_thread_stack_pointer : thread.pStack));
  return encoder.status();
#endif  // OS_CHECKSTACK || OS_SUPPORT_MPU
}

}  // namespace pw::thread::embos
