#pragma once

#include "ELF.h"
#include "arch/CPU.h"
#include "arch/MMU.h"
#include "fs/VFS.h"
#include "memory/AddressSpace.h"
#include "thread/Thread.h"
#include <luna/LinkedList.h>
#include <luna/OwnedPtr.h>
#include <luna/Result.h>
#include <luna/Stack.h>
#include <luna/String.h>
#include <luna/Vector.h>

class Thread;

class ThreadImage
{
  public:
    static Result<OwnedPtr<ThreadImage>> try_load_from_elf(SharedPtr<VFS::Inode> inode);

    static Result<OwnedPtr<ThreadImage>> clone_from_thread(Thread* parent);

    Result<u64> push_mem_on_stack(const u8* mem, usize size);
    Result<u64> push_string_vector_on_stack(const Vector<String>& vec);

    void apply(Thread* thread);

  private:
    OwnedPtr<AddressSpace> m_address_space;
    Stack m_user_stack;
    Stack m_kernel_stack;
    ELFData m_loaded_image_data;
    u64 m_sp;
};