// 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.
#pragma once

#include "pw_assert/assert.h"
#include "pw_thread/thread.h"
#include "pw_thread_threadx/config.h"
#include "pw_thread_threadx/context.h"
#include "tx_api.h"

namespace pw::thread::threadx {

// pw::thread::Options for ThreadX.
//
// Example usage:
//
//   // Uses the default priority and time slice interval (which may be
//   // disabled), but specifies a custom name and pre-allocated context.
//   // Note that the preemption threshold is disabled by default.
//   pw::thread::Thread example_thread(
//     pw::thread::threadx::Options()
//         .set_name("example_thread"),
//         .set_context(static_example_thread_context),
//     example_thread_function);
//
//   // Specifies the name, priority, time slice interval, and pre-allocated
//   // context, but does not use a preemption threshold.
//   pw::thread::Thread static_example_thread(
//     pw::thread::threadx::Options()
//         .set_name("static_example_thread")
//         .set_priority(kFooPriority)
//         .set_time_slice_interval(1)
//         .set_context(static_example_thread_context),
//     example_thread_function);
//
class Options : public thread::Options {
 public:
  constexpr Options() = default;
  constexpr Options(const Options&) = default;
  constexpr Options(Options&& other) = default;

  // Sets the name for the ThreadX thread, note that this will be deep copied
  // into the context and may be truncated based on
  // PW_THREAD_THREADX_CONFIG_MAX_THREAD_NAME_LEN.
  constexpr Options set_name(const char* name) {
    name_ = name;
    return *this;
  }

  // Sets the priority for the ThreadX thread from 0 through 31, where a value
  // of 0 represents the highest priority, see ThreadX tx_thread_create for
  // more detail.
  constexpr Options set_priority(UINT priority) {
    PW_DASSERT(priority <= PW_THREAD_THREADX_CONFIG_MIN_PRIORITY);
    priority_ = priority;
    return *this;
  }

  // Optionally sets the preemption threshold for the ThreadX thread from 0
  // through 31.
  //
  // Only priorities higher than this level (i.e. lower number) are allowed to
  // preempt this thread. In other words this allows the thread to specify the
  // priority ceiling for disabling preemption. Threads that have a higher
  // priority than the ceiling are still allowed to preempt while those with
  // less than the ceiling are not allowed to preempt.
  //
  // Not setting the preemption threshold or explicitly specifying a value
  // equal to the priority disables preemption threshold.
  //
  // Time slicing is disabled while the preemption threshold is enabled, i.e.
  // not equal to the priority, even if a time slice interval was specified.
  //
  // The preemption threshold can be adjusted at run time, this only sets the
  // initial threshold.
  //
  // Precondition: preemption_threshold <= priority
  constexpr Options set_preemption_threshold(UINT preemption_threshold) {
    PW_DASSERT(preemption_threshold < PW_THREAD_THREADX_CONFIG_MIN_PRIORITY);
    possible_preemption_threshold_ = preemption_threshold;
    return *this;
  }

  // Sets the number of ticks this thread is allowed to run before other ready
  // threads of the same priority are given a chance to run.
  //
  // Time slicing is disabled while the preemption threshold is enabled, i.e.
  // not equal to the priority, even if a time slice interval was specified.
  //
  // A value of TX_NO_TIME_SLICE (a value of 0) disables time-slicing of this
  // thread.
  //
  // Using time slicing results in a slight amount of system overhead, threads
  // with a unique priority should consider TX_NO_TIME_SLICE.
  constexpr Options set_time_slice_interval(ULONG time_slice_interval) {
    time_slice_interval_ = time_slice_interval;
    return *this;
  }

  // Set the pre-allocated context (all memory needed to run a thread), see the
  // pw::thread::threadx::Context for more detail.
  constexpr Options set_context(Context& context) {
    context_ = &context;
    return *this;
  }

 private:
  friend thread::Thread;
  // Note that the default name may end up truncated due to
  // PW_THREAD_THREADX_CONFIG_MAX_THREAD_NAME_LEN.
  static constexpr char kDefaultName[] = "pw::Thread";

  const char* name() const { return name_; }
  UINT priority() const { return priority_; }
  UINT preemption_threshold() const {
    return possible_preemption_threshold_.value_or(priority_);
  }
  ULONG time_slice_interval() const { return time_slice_interval_; }
  Context* context() const { return context_; }

  const char* name_ = kDefaultName;
  UINT priority_ = config::kDefaultPriority;
  // A default value cannot be used for the preemption threshold as it would
  // have to be based on the selected priority.
  std::optional<UINT> possible_preemption_threshold_ = std::nullopt;
  ULONG time_slice_interval_ = config::kDefaultTimeSliceInterval;
  Context* context_ = nullptr;
};

}  // namespace pw::thread::threadx
