#pragma once

#include <euler/syscall.hpp>

namespace euler {

  class stream {

  public:
    virtual ~stream() {}

    virtual syscall::stream_result seek(
      euler::syscall::seek_from from, int64_t offset) = 0;

    virtual std::pair<uint64_t, syscall::stream_result>
      read(uint64_t bytes, void *into) = 0;

    virtual void close() = 0;

  };

  class file_stream : public stream {

    syscall::stream_handle handle;
    bool may_read;

    bool buffer_loaded;
    uint64_t buffer_start;
    uint8_t buffer[1024];

    uint64_t length;
    uint64_t position;

  public:
    file_stream(
      syscall::stream_handle handle, bool may_read,
      uint64_t length, uint64_t position);

    virtual syscall::stream_result seek(
      syscall::seek_from from, int64_t offset) override;

    virtual std::pair<uint64_t, syscall::stream_result>
      read(uint64_t bytes, void *into) override;

    virtual void close() override;

  };

}
