// #hacky fwd declares
struct Thread;
struct Error;
struct Graphics;

struct Thread_Context {
  ExpandableArena* temp;  // Used for temporary allocations, scratch space.
  ExpandableArena* arena; // general purpose local arena

  Allocator allocator;
  s32 thread_idx;
  u16 _padding0;
  u16 GPAllocator_alignment = 16;
  Logger logger = {nullptr, nullptr};
  String_Builder* log_builder;
  // Stack_Trace* stack_trace;
  
  Array<Thread*> child_threads; // maybe should be linked-list?
  Thread_Context* parent_thread_context = nullptr; // so we can remove from above array
  
  string thread_name;
  
  Allocator error_allocator = GPAllocator();
  Error* first_error = nullptr;
  Error* current_error = nullptr;
  Arena* error_arena;
  
  // Graphics stuff:
  Graphics* graphics;
};

// C_LINKAGE thread_static TCTX* tctx_thread_local;
thread_static Thread_Context* thread_local_context;

// #TODO #NewContext void create_thread_context (Thread_Context** context, string thread_name, bool is_main_thread);
// Thread-context #Errors:

internal void Bootstrap_Main_Thread_Context ();

struct Push_Allocator {
  Thread_Context* context;
  Allocator old_allocator;
  
  Push_Allocator (Allocator new_allocator) {
    context = thread_context();
    old_allocator = context->allocator;
    context->allocator = new_allocator;
  }
  
  ~Push_Allocator () {
    context->allocator = old_allocator;
  }
};

