// Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/bio.h>

#include <assert.h>
#include <string.h>

#include <openssl/err.h>
#include <openssl/mem.h>

#include "../internal.h"
#include "../mem_internal.h"
#include "internal.h"


using namespace bssl;

namespace {
struct bio_bio_st {
  BIO *peer = nullptr;  // NULL if buf == NULL.
                        // If peer != NULL, then BIO_get_data(peer) is also a
                        // bio_bio_st, and its "peer" member points back to us.
                        // peer != NULL iff init != 0 in the BIO.

  // This is for what we write (i.e. reading uses peer's struct):
  int closed = 0;     // valid iff peer != NULL
  size_t len = 0;     // valid iff buf != NULL; 0 if peer == NULL
  size_t offset = 0;  // valid iff buf != NULL; 0 if len == 0
  size_t size = 0;
  uint8_t *buf = nullptr;  // "size" elements (if != NULL)

  size_t request = 0;  // valid iff peer != NULL; 0 if len != 0,
                       // otherwise set by peer to number of bytes
                       // it (unsuccessfully) tried to read,
                       // never more than buffer space (size-len) warrants.
};
}  // namespace

static int bio_new(BIO *bio) {
  struct bio_bio_st *b = New<struct bio_bio_st>();
  if (b == nullptr) {
    return 0;
  }

  b->size = 17 * 1024;  // enough for one TLS record (just a default)
  BIO_set_data(bio, b);
  return 1;
}

static void bio_destroy_pair(BIO *bio) {
  struct bio_bio_st *b = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio));
  BIO *peer_bio;
  struct bio_bio_st *peer_b;

  if (b == nullptr) {
    return;
  }

  peer_bio = b->peer;
  if (peer_bio == nullptr) {
    return;
  }

  peer_b = reinterpret_cast<bio_bio_st *>(BIO_get_data(peer_bio));

  assert(peer_b != nullptr);
  assert(peer_b->peer == bio);

  peer_b->peer = nullptr;
  BIO_set_init(peer_bio, 0);
  assert(peer_b->buf != nullptr);
  peer_b->len = 0;
  peer_b->offset = 0;

  b->peer = nullptr;
  BIO_set_init(bio, 0);
  assert(b->buf != nullptr);
  b->len = 0;
  b->offset = 0;
}

static int bio_free(BIO *bio) {
  struct bio_bio_st *b = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio));

  assert(b != nullptr);

  if (b->peer) {
    bio_destroy_pair(bio);
  }

  OPENSSL_free(b->buf);
  Delete(b);

  return 1;
}

static int bio_read(BIO *bio, char *buf, int size_) {
  size_t size = size_;

  BIO_clear_retry_flags(bio);

  bio_bio_st *b = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio));
  assert(b != nullptr);
  assert(b->peer != nullptr);
  bio_bio_st *peer_b = reinterpret_cast<bio_bio_st *>(BIO_get_data(b->peer));
  assert(peer_b != nullptr);
  assert(peer_b->buf != nullptr);

  peer_b->request = 0;  // will be set in "retry_read" situation

  if (peer_b->len == 0) {
    if (peer_b->closed) {
      return 0;  // writer has closed, and no data is left
    } else {
      BIO_set_retry_read(bio);  // buffer is empty
      if (size <= peer_b->size) {
        peer_b->request = size;
      } else {
        // don't ask for more than the peer can
        // deliver in one write
        peer_b->request = peer_b->size;
      }
      return -1;
    }
  }

  // we can read
  if (peer_b->len < size) {
    size = peer_b->len;
  }

  // now read "size" bytes
  size_t rest = size;

  assert(rest > 0);
  // one or two iterations
  do {
    size_t chunk;

    assert(rest <= peer_b->len);
    if (peer_b->offset + rest <= peer_b->size) {
      chunk = rest;
    } else {
      // wrap around ring buffer
      chunk = peer_b->size - peer_b->offset;
    }
    assert(peer_b->offset + chunk <= peer_b->size);

    OPENSSL_memcpy(buf, peer_b->buf + peer_b->offset, chunk);

    peer_b->len -= chunk;
    if (peer_b->len) {
      peer_b->offset += chunk;
      assert(peer_b->offset <= peer_b->size);
      if (peer_b->offset == peer_b->size) {
        peer_b->offset = 0;
      }
      buf += chunk;
    } else {
      // buffer now empty, no need to advance "buf"
      assert(chunk == rest);
      peer_b->offset = 0;
    }
    rest -= chunk;
  } while (rest);

  // `size` is bounded by the buffer size, which fits in `int`.
  return (int)size;
}

static int bio_write_ex(BIO *bio, const char *buf, size_t num,
                        size_t *out_written) {
  BIO_clear_retry_flags(bio);

  struct bio_bio_st *b = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio));
  assert(b != nullptr);
  assert(b->peer != nullptr);
  assert(b->buf != nullptr);

  b->request = 0;
  if (b->closed) {
    // we already closed
    OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
    return 0;
  }

  assert(b->len <= b->size);

  if (b->len == b->size) {
    BIO_set_retry_write(bio);  // buffer is full
    return 0;
  }

  // we can write
  if (num > b->size - b->len) {
    num = b->size - b->len;
  }

  // now write "num" bytes
  size_t rest = num;

  assert(rest > 0);
  // one or two iterations
  do {
    size_t write_offset;
    size_t chunk;

    assert(b->len + rest <= b->size);

    write_offset = b->offset + b->len;
    if (write_offset >= b->size) {
      write_offset -= b->size;
    }
    // b->buf[write_offset] is the first byte we can write to.

    if (write_offset + rest <= b->size) {
      chunk = rest;
    } else {
      // wrap around ring buffer
      chunk = b->size - write_offset;
    }

    OPENSSL_memcpy(b->buf + write_offset, buf, chunk);

    b->len += chunk;

    assert(b->len <= b->size);

    rest -= chunk;
    buf += chunk;
  } while (rest);

  *out_written = num;
  return 1;
}

static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len,
                         size_t writebuf2_len) {
  struct bio_bio_st *b1, *b2;

  assert(bio1 != nullptr);
  assert(bio2 != nullptr);

  b1 = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio1));
  b2 = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio2));

  if (b1->peer != nullptr || b2->peer != nullptr) {
    OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE);
    return 0;
  }

  if (b1->buf == nullptr) {
    if (writebuf1_len) {
      b1->size = writebuf1_len;
    }
    b1->buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(b1->size));
    if (b1->buf == nullptr) {
      return 0;
    }
    b1->len = 0;
    b1->offset = 0;
  }

  if (b2->buf == nullptr) {
    if (writebuf2_len) {
      b2->size = writebuf2_len;
    }
    b2->buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(b2->size));
    if (b2->buf == nullptr) {
      return 0;
    }
    b2->len = 0;
    b2->offset = 0;
  }

  b1->peer = bio2;
  b1->closed = 0;
  b1->request = 0;
  b2->peer = bio1;
  b2->closed = 0;
  b2->request = 0;

  BIO_set_init(bio1, 1);
  BIO_set_init(bio2, 1);

  return 1;
}

static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
  struct bio_bio_st *b = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio));
  assert(b != nullptr);
  switch (cmd) {
    // Specific control codes first:
    case BIO_C_GET_WRITE_BUF_SIZE:
      // TODO(crbug.com/412584975): This can overflow on 64-bit Windows. Do we
      // need it? It implements `BIO_get_write_buf_size`, but we don't have the
      // wrapper.
      return static_cast<long>(b->size);

    case BIO_C_GET_WRITE_GUARANTEE:
      // How many bytes can the caller feed to the next write
      // without having to keep any?
      if (b->peer == nullptr || b->closed) {
        return 0;
      }
      // TODO(crbug.com/412584975): This can overflow on 64-bit Windows.
      return static_cast<long>(b->size - b->len);

    case BIO_C_GET_READ_REQUEST:
      // If the peer unsuccessfully tried to read, how many bytes
      // were requested?  (As with BIO_CTRL_PENDING, that number
      // can usually be treated as boolean.)
      //
      // TODO(crbug.com/412584975): This can overflow on 64-bit Windows.
      return static_cast<long>(b->request);

    case BIO_C_RESET_READ_REQUEST:
      // Reset request.  (Can be useful after read attempts
      // at the other side that are meant to be non-blocking,
      // e.g. when probing SSL_read to see if any data is
      // available.)
      b->request = 0;
      return 1;

    case BIO_C_SHUTDOWN_WR:
      // similar to shutdown(..., SHUT_WR)
      b->closed = 1;
      return 1;

    // Standard control codes:
    case BIO_CTRL_GET_CLOSE:
      return BIO_get_shutdown(bio);

    case BIO_CTRL_SET_CLOSE:
      BIO_set_shutdown(bio, static_cast<int>(num));
      return 1;

    case BIO_CTRL_PENDING:
      if (b->peer != nullptr) {
        struct bio_bio_st *peer_b =
            reinterpret_cast<bio_bio_st *>(BIO_get_data(b->peer));
        // TODO(crbug.com/412584975): This can overflow on 64-bit Windows.
        return static_cast<long>(peer_b->len);
      }
      return 0;

    case BIO_CTRL_WPENDING:
      if (b->buf == nullptr) {
        return 0;
      }
      // TODO(crbug.com/412584975): This can overflow on 64-bit Windows.
      return static_cast<long>(b->len);

    case BIO_CTRL_FLUSH:
      return 1;

    case BIO_CTRL_EOF: {
      if (b->peer) {
        auto *peer_b = reinterpret_cast<bio_bio_st *>(BIO_get_data(b->peer));
        assert(peer_b != nullptr);
        return peer_b->len == 0 && peer_b->closed;
      }
      return 1;
    }

    default:
      return 0;
  }
}


static const BIO_METHOD methods_biop = {
    BIO_TYPE_BIO,
    "BIO pair",
    /*bwrite=*/nullptr,
    bio_write_ex,
    bio_read,
    /*gets=*/nullptr,
    bio_ctrl,
    bio_new,
    bio_free,
    /*callback_ctrl=*/nullptr,
};

static const BIO_METHOD *bio_s_bio() { return &methods_biop; }

int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1_len, BIO **bio2_p,
                     size_t writebuf2_len) {
  BIO *bio1 = BIO_new(bio_s_bio());
  BIO *bio2 = BIO_new(bio_s_bio());
  if (bio1 == nullptr || bio2 == nullptr ||
      !bio_make_pair(bio1, bio2, writebuf1_len, writebuf2_len)) {
    BIO_free(bio1);
    BIO_free(bio2);
    *bio1_p = nullptr;
    *bio2_p = nullptr;
    return 0;
  }

  *bio1_p = bio1;
  *bio2_p = bio2;
  return 1;
}

size_t BIO_ctrl_get_read_request(BIO *bio) {
  return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, nullptr);
}

size_t BIO_ctrl_get_write_guarantee(BIO *bio) {
  return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, nullptr);
}

int BIO_shutdown_wr(BIO *bio) {
  return (int)BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, nullptr);
}
