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