// Copyright 2019 The Marl 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.

#ifndef marl_thread_h
#define marl_thread_h

#include "containers.h"
#include "export.h"

#include <functional>

namespace marl {

// Thread provides an OS abstraction for threads of execution.
class Thread {
 public:
  using Func = std::function<void()>;

  // Core identifies a logical processor unit.
  // How a core is identified varies by platform.
  struct Core {
    struct Windows {
      uint8_t group;  // Group number
      uint8_t index;  // Core within the processor group
    };
    struct Pthread {
      uint16_t index;  // Core number
    };
    union {
      Windows windows;
      Pthread pthread;
    };

    // Comparison functions
    MARL_NO_EXPORT inline bool operator==(const Core&) const;
    MARL_NO_EXPORT inline bool operator<(const Core&) const;
  };

  // Affinity holds the affinity mask for a thread - a description of what cores
  // the thread is allowed to run on.
  struct Affinity {
    // supported is true if marl supports controlling thread affinity for this
    // platform.
#if defined(_WIN32) || (defined(__linux__) && !defined(__ANDROID__)) || \
    defined(__FreeBSD__)
    static constexpr bool supported = true;
#else
    static constexpr bool supported = false;
#endif

    // Policy is an interface that provides a get() method for returning an
    // Affinity for the given thread by id.
    class Policy {
     public:
      virtual ~Policy() {}

      // anyOf() returns a Policy that returns an Affinity for a number of
      // available cores in affinity.
      //
      // Windows requires that each thread is only associated with a
      // single affinity group, so the Policy's returned affinity will contain
      // cores all from the same group.
      MARL_EXPORT static std::shared_ptr<Policy> anyOf(
          Affinity&& affinity,
          Allocator* allocator = Allocator::Default);

      // oneOf() returns a Policy that returns an affinity with a single enabled
      // core from affinity. The single enabled core in the Policy's returned
      // affinity is:
      //      affinity[threadId % affinity.count()]
      MARL_EXPORT static std::shared_ptr<Policy> oneOf(
          Affinity&& affinity,
          Allocator* allocator = Allocator::Default);

      // get() returns the thread Affinity for the for the given thread by id.
      MARL_EXPORT virtual Affinity get(uint32_t threadId,
                                       Allocator* allocator) const = 0;
    };

    MARL_EXPORT Affinity(Allocator*);

    MARL_EXPORT Affinity(Affinity&&);

    MARL_EXPORT Affinity(const Affinity&, Allocator* allocator);

    // all() returns an Affinity with all the cores available to the process.
    MARL_EXPORT static Affinity all(Allocator* allocator = Allocator::Default);

    MARL_EXPORT Affinity(std::initializer_list<Core>, Allocator* allocator);

    // count() returns the number of enabled cores in the affinity.
    MARL_EXPORT size_t count() const;

    // operator[] returns the i'th enabled core from this affinity.
    MARL_EXPORT Core operator[](size_t index) const;

    // add() adds the cores from the given affinity to this affinity.
    // This affinity is returned to allow for fluent calls.
    MARL_EXPORT Affinity& add(const Affinity&);

    // remove() removes the cores from the given affinity from this affinity.
    // This affinity is returned to allow for fluent calls.
    MARL_EXPORT Affinity& remove(const Affinity&);

   private:
    Affinity(const Affinity&) = delete;

    containers::vector<Core, 32> cores;
  };

  MARL_EXPORT Thread() = default;

  MARL_EXPORT Thread(Thread&&);

  MARL_EXPORT Thread& operator=(Thread&&);

  // Start a new thread using the given affinity that calls func.
  MARL_EXPORT Thread(Affinity&& affinity, Func&& func);

  MARL_EXPORT ~Thread();

  // join() blocks until the thread completes.
  MARL_EXPORT void join();

  // setName() sets the name of the currently executing thread for displaying
  // in a debugger.
  MARL_EXPORT static void setName(const char* fmt, ...);

  // numLogicalCPUs() returns the number of available logical CPU cores for
  // the system.
  MARL_EXPORT static unsigned int numLogicalCPUs();

 private:
  Thread(const Thread&) = delete;
  Thread& operator=(const Thread&) = delete;

  class Impl;
  Impl* impl = nullptr;
};

////////////////////////////////////////////////////////////////////////////////
// Thread::Core
////////////////////////////////////////////////////////////////////////////////
// Comparison functions
bool Thread::Core::operator==(const Core& other) const {
  return pthread.index == other.pthread.index;
}

bool Thread::Core::operator<(const Core& other) const {
  return pthread.index < other.pthread.index;
}

}  // namespace marl

#endif  // marl_thread_h
