#pragma once
#include <filesystem>
#include <fstream>
#include <functional>
#include <sstream>
#include "asset.h"
#include "singleton.h"
#include <nlohmann/json.hpp>
using json = nlohmann::json;
namespace engineapi
{
    class AssetManager : public Singleton<AssetManager>
    {
    public:
        struct AssetWrap {
            Asset* asset;
            uint32_t count;
            AssetWrap(Asset* asset): asset(asset),count(1) {

            }
        };

    private:
        map<const string, AssetWrap> mAssetMap;
    public:
        void ClearAsset(Asset* asset);
        template<typename TAsset>
        TAsset* LoadAsset(const string& name, uint32_t flags)
        {
            auto it = mAssetMap.find(name);
            bool isFind = it != mAssetMap.end();
            if (isFind) {
                it->second.count++;
                if (it->second.asset->IsShared()) {
                    return (TAsset*)(it->second.asset);
                }
                if (it->second.asset->IsCopyed()) {
                    TAsset* asset = new TAsset(name, flags);
                    *asset = *(TAsset*)(it->second.asset);
                    return asset;
                }
            }
            TAsset* asset = new TAsset(name, flags);
            if (!isFind && (asset->IsShared() || asset->IsCopyed())) {
                mAssetMap.emplace(name, asset);
            }
            asset->BeginLoad();
            return asset;
        }

        AssetManager() = default;
    public:
        static string LoadTextFile(const string& path);
        static vector<char> LoadBinaryFile(const string& path);
        static json LoadJsonFile(const string& path);
    };
}
template<>
engineapi::AssetManager* Singleton<engineapi::AssetManager>::ms_Singleton = nullptr;
