/*
 * Copyright (c) 2026, Chloe M.
 * Provided under the BSD-3 clause.
 *
 * Description: Process management
 * Author:      Chloe M.
 */

#include <ps/process.h>
#include <ex/pool.h>
#include <string.h>
#include <atomic.h>

static UQUAD ProcessId = 0;

PT_STATUS
PsCreateProcess(const CHAR *Name, ULONG Flags, PROCESS **Result)
{
    USIZE NameLen;
    PROCESS *Process;
    MMU_VAS CurrentVas;
    PT_STATUS Status;

    if (Name == NULL || Result == NULL) {
        return STATUS_INVALID_PARAM;
    }

    NameLen = RtlStrLen(Name);
    if (NameLen >= PS_NAME_MAX - 1) {
        return STATUS_NAME_TOO_LONG;
    }

    Process = ExAllocatePoolWithTag(
        POOL_NON_PAGED,
        sizeof(*Process),
        PS_POOL_TAG
    );

    if (Process == NULL) {
        return STATUS_NO_MEMORY;
    }

    /* Fork a new VAS */
    HalMmuReadVas(&CurrentVas);
    Status = HalMmuForkVas(&CurrentVas, &Process->Vas);
    if (PT_ERROR(Status)) {
        ExFreePoolWithTag(Process, PS_POOL_TAG);
        return Status;
    }

    RtlMemCpy(Process->Name, Name, NameLen);
    Process->Pid = AtomicIncQuad(&ProcessId);
    Process->Flags = Flags;
    *Result = Process;
    return STATUS_SUCCESS;
}
