// Copyright © Amer Koleci and Contributors.
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.

#include "IO/Path.h"
#include "IO/FileSystem.h"
#include "IO/FileStream.h"
#include "Core/Log.h"
#include "Core/Assert.h"
#ifdef _WIN32
#   include "PlatformInclude.h"
#else
#   include <unistd.h>
#   ifdef __linux__
#       include <linux/limits.h>
#   endif
#endif
#include <filesystem>
namespace fs = std::filesystem;

namespace Alimer
{
    namespace File
    {
        bool Exists(const FilePath& path)
        {
            try
            {
                if (fs::exists(path))
                    return true;
            }
            catch (fs::filesystem_error& e)
            {
                LOGW("{}, {}", e.what(), path.c_str());
            }

            return false;
        }

        bool Delete(const FilePath& path)
        {
            try
            {
                if (fs::exists(path) && fs::remove_all(path))
                    return true;
            }
            catch (fs::filesystem_error& e)
            {
                LOGW("{}, {}", e.what(), path.c_str());
            }

            return false;
        }

        std::string ReadAllText(const FilePath& path)
        {
            if (!File::Exists(path))
                return {};

            FileStream stream(path, FileMode::OpenRead);
            std::string result = stream.ReadString();
            return result;
        }

        std::vector<uint8_t> ReadAllBytes(const FilePath& path)
        {
            if (!File::Exists(path))
                return {};

            FileStream stream(path, FileMode::OpenRead);
            return stream.ReadBytes();
        }

        bool ReadAllBytes(const FilePath& path, std::vector<uint8_t>& data)
        {
            if (!File::Exists(path))
                return false;

            FileStream stream(path, FileMode::OpenRead);
            stream.ReadBytes(data);
            return true;
        }

        void Write(const FilePath& path, const std::vector<uint8_t>& data, const uint32_t count)
        {
            FileStream file(path, FileMode::CreateWrite);
            if (!file.IsOpen())
            {
                throw std::runtime_error("Failed to open file: " + path);
            }

            size_t writeCount = count;
            if (count == 0)
            {
                writeCount = data.size();
            }

            file.Write(data.data(), writeCount);
            file.Close();
        }
    }
}
