#include <windows.h>
#include <stdexcept>

#include "../include/System/IO/FileStream.h"

namespace System::IO {
    FileStream::FileStream(const std::wstring& filePath, 
                           DWORD access, 
                           DWORD creationDisposition, 
                           DWORD shareMode, 
                           DWORD flagsAndAttributes)
        : path(filePath)
    {
        hFile = CreateFileW(filePath.c_str(), access, shareMode, nullptr, creationDisposition, flagsAndAttributes, nullptr);
        if (hFile == INVALID_HANDLE_VALUE)
            throw std::runtime_error("Unable to open file.");
    }

    FileStream::~FileStream() {
        if (hFile != INVALID_HANDLE_VALUE)
            CloseHandle(hFile);
    }

    bool FileStream::Read(void* buffer, DWORD numBytesToRead, DWORD& numBytesRead) {
        return ReadFile(hFile, buffer, numBytesToRead, &numBytesRead, nullptr) != 0;
    }

    bool FileStream::Write(const void* buffer, DWORD numBytesToWrite, DWORD& numBytesWritten) {
        return WriteFile(hFile, buffer, numBytesToWrite, &numBytesWritten, nullptr) != 0;
    }

    bool FileStream::Seek(LARGE_INTEGER offset, DWORD moveMethod, ULARGE_INTEGER& newPos) {
        LARGE_INTEGER tempPos = { 0 };
        BOOL result = SetFilePointerEx(hFile, offset, &tempPos, moveMethod);
        newPos.QuadPart = static_cast<ULONGLONG>(tempPos.QuadPart);
        return result != 0;
    }

    bool FileStream::SetEnd() {
        return SetEndOfFile(hFile) != 0;
    }
}