#pragma once

#include <util/system/fstat.h>
#include <util/system/file.h>
#include <util/stream/file.h>
#include <util/folder/path.h>

namespace NSrvKernel {

class IFileArbiter {
public:
    virtual ~IFileArbiter() = default;

    virtual TFileStat GetStat(const char* path, bool nofollow = false) const = 0;
    virtual TFileStat GetStat(FHANDLE f) const = 0;

    virtual TFileStat GetStat(const TFsPath& path, bool nofollow = false) const {
        return GetStat(path.GetPath().data(), nofollow);
    }

    virtual TFileStat GetStat(const TString& path, bool nofollow = false) const {
        return GetStat(path.data(), nofollow);
    }

    virtual TFileStat GetStat(const TFile& f) const { return GetStat(f.GetHandle()); }

    virtual THolder<IInputStream> GetInput(const TFile& file) const = 0;
    virtual THolder<IInputStream> GetInput(const TString& path) const = 0;
};

class TFileArbiter final : public IFileArbiter {
public:
    TFileStat GetStat(const char* path, bool nofollow) const override {
        return TFileStat(path, nofollow);
    }
    TFileStat GetStat(FHANDLE f) const override { return TFileStat(f); }

    TFileStat GetStat(const TFsPath& path, bool nofollow = false) const override {
        return TFileStat(path, nofollow);
    }

    TFileStat GetStat(const TString& path, bool nofollow = false) const override {
        return TFileStat(path, nofollow);
    }

    TFileStat GetStat(const TFile& f) const override { return TFileStat(f); }

    THolder<IInputStream> GetInput(const TFile& file) const override {
        return MakeHolder<TFileInput>(file);
    }

    THolder<IInputStream> GetInput(const TString& path) const override {
        return MakeHolder<TFileInput>(path);
    }
};

}  // namespace NSrvKernel
