import * as ops from '../ops';

let next_thread_id = 1;

export default class file {
  constructor(conn, handle, remote_path) {
    this.conn = conn;
    this.handle = handle || null;
    this.remote_path = remote_path;
    this.thread_id = next_thread_id++;
  }

  conn;
  handle = null;
  thread_id;
  remote_path;

  async close() {
    if (this.handle !== null) {
      const result = await ops.close_file(
        this.conn,
        this.remote_path,
        this.handle,
        this.thread_id
      );
      if (result === 0) {
        this.handle = null;
      }
      return result;
    }

    return 0;
  }

  async get_size() {
    if (this.handle === null) {
      return Promise.reject(new Error("'get_size()' failed: invalid handle"));
    }

    const attrs = await ops.get_file_attributes(
      this.conn,
      this.handle,
      this.remote_path,
      this.thread_id
    );
    return attrs.size;
  }

  async read(offset, length) {
    if (this.handle === null) {
      return Promise.reject(new Error("'read()' failed: invalid handle"));
    }

    return ops.read_file(
      this.conn,
      this.handle,
      this.remote_path,
      offset,
      length,
      this.thread_id
    );
  }

  async truncate(length) {
    if (this.handle === null) {
      return Promise.reject(new Error("'truncate()' failed: invalid handle"));
    }

    return ops.truncate_file(
      this.conn,
      this.handle,
      this.remote_path,
      length,
      this.thread_id
    );
  }

  async write(offset, buffer) {
    if (this.handle === null) {
      return Promise.reject(new Error("'write()' failed: invalid handle"));
    }

    return ops.write_file(
      this.conn,
      this.handle,
      this.remote_path,
      offset,
      buffer,
      this.thread_id
    );
  }
}
