// Copyright (c) 2008 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "libcef/browser/stream_impl.h"
#include <stdlib.h>
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/threading/thread_restrictions.h"

// Static functions

CefRefPtr<CefStreamReader> CefStreamReader::CreateForFile(
    const CefString& fileName) {
  DCHECK(!fileName.empty());

  // TODO(cef): Do not allow file IO on all threads (issue #1187).
  base::ThreadRestrictions::ScopedAllowIO allow_io;

  CefRefPtr<CefStreamReader> reader;
  FILE* file = base::OpenFile(base::FilePath(fileName), "rb");
  if (file)
    reader = new CefFileReader(file, true);
  return reader;
}

CefRefPtr<CefStreamReader> CefStreamReader::CreateForData(void* data,
                                                          size_t size) {
  DCHECK(data != nullptr);
  DCHECK(size > 0);
  CefRefPtr<CefStreamReader> reader;
  if (data && size > 0)
    reader = new CefBytesReader(data, size, true);
  return reader;
}

CefRefPtr<CefStreamReader> CefStreamReader::CreateForHandler(
    CefRefPtr<CefReadHandler> handler) {
  DCHECK(handler.get());
  CefRefPtr<CefStreamReader> reader;
  if (handler.get())
    reader = new CefHandlerReader(handler);
  return reader;
}

CefRefPtr<CefStreamWriter> CefStreamWriter::CreateForFile(
    const CefString& fileName) {
  DCHECK(!fileName.empty());

  // TODO(cef): Do not allow file IO on all threads (issue #1187).
  base::ThreadRestrictions::ScopedAllowIO allow_io;

  CefRefPtr<CefStreamWriter> writer;
  FILE* file = base::OpenFile(base::FilePath(fileName), "wb");
  if (file)
    writer = new CefFileWriter(file, true);
  return writer;
}

CefRefPtr<CefStreamWriter> CefStreamWriter::CreateForHandler(
    CefRefPtr<CefWriteHandler> handler) {
  DCHECK(handler.get());
  CefRefPtr<CefStreamWriter> writer;
  if (handler.get())
    writer = new CefHandlerWriter(handler);
  return writer;
}

// CefFileReader

CefFileReader::CefFileReader(FILE* file, bool close)
    : close_(close), file_(file) {}

CefFileReader::~CefFileReader() {
  base::AutoLock lock_scope(lock_);
  if (close_)
    base::CloseFile(file_);
}

size_t CefFileReader::Read(void* ptr, size_t size, size_t n) {
  base::AutoLock lock_scope(lock_);
  return fread(ptr, size, n, file_);
}

int CefFileReader::Seek(int64 offset, int whence) {
  base::AutoLock lock_scope(lock_);
#if defined(OS_WIN)
  return _fseeki64(file_, offset, whence);
#else
  return fseek(file_, offset, whence);
#endif
}

int64 CefFileReader::Tell() {
  base::AutoLock lock_scope(lock_);
#if defined(OS_WIN)
  return _ftelli64(file_);
#else
  return ftell(file_);
#endif
}

int CefFileReader::Eof() {
  base::AutoLock lock_scope(lock_);
  return feof(file_);
}

// CefFileWriter

CefFileWriter::CefFileWriter(FILE* file, bool close)
    : file_(file), close_(close) {}

CefFileWriter::~CefFileWriter() {
  base::AutoLock lock_scope(lock_);
  if (close_)
    base::CloseFile(file_);
}

size_t CefFileWriter::Write(const void* ptr, size_t size, size_t n) {
  base::AutoLock lock_scope(lock_);
  return (size_t)fwrite(ptr, size, n, file_);
}

int CefFileWriter::Seek(int64 offset, int whence) {
  base::AutoLock lock_scope(lock_);
  return fseek(file_, offset, whence);
}

int64 CefFileWriter::Tell() {
  base::AutoLock lock_scope(lock_);
  return ftell(file_);
}

int CefFileWriter::Flush() {
  base::AutoLock lock_scope(lock_);
  return fflush(file_);
}

// CefBytesReader

CefBytesReader::CefBytesReader(void* data, int64 datasize, bool copy)
    : data_(nullptr), datasize_(0), copy_(false), offset_(0) {
  SetData(data, datasize, copy);
}

CefBytesReader::~CefBytesReader() {
  SetData(nullptr, 0, false);
}

size_t CefBytesReader::Read(void* ptr, size_t size, size_t n) {
  base::AutoLock lock_scope(lock_);
  size_t s = (datasize_ - offset_) / size;
  size_t ret = (n < s ? n : s);
  memcpy(ptr, (reinterpret_cast<char*>(data_)) + offset_, ret * size);
  offset_ += ret * size;
  return ret;
}

int CefBytesReader::Seek(int64 offset, int whence) {
  int rv = -1L;
  base::AutoLock lock_scope(lock_);
  switch (whence) {
    case SEEK_CUR:
      if (offset_ + offset > datasize_ || offset_ + offset < 0)
        break;
      offset_ += offset;
      rv = 0;
      break;
    case SEEK_END: {
      int64 offset_abs = std::abs(offset);
      if (offset_abs > datasize_)
        break;
      offset_ = datasize_ - offset_abs;
      rv = 0;
      break;
    }
    case SEEK_SET:
      if (offset > datasize_ || offset < 0)
        break;
      offset_ = offset;
      rv = 0;
      break;
  }

  return rv;
}

int64 CefBytesReader::Tell() {
  base::AutoLock lock_scope(lock_);
  return offset_;
}

int CefBytesReader::Eof() {
  base::AutoLock lock_scope(lock_);
  return (offset_ >= datasize_);
}

void CefBytesReader::SetData(void* data, int64 datasize, bool copy) {
  base::AutoLock lock_scope(lock_);
  if (copy_)
    free(data_);

  copy_ = copy;
  offset_ = 0;
  datasize_ = datasize;

  if (copy) {
    data_ = malloc(datasize);
    DCHECK(data_ != nullptr);
    if (data_)
      memcpy(data_, data, datasize);
  } else {
    data_ = data;
  }
}

// CefBytesWriter

CefBytesWriter::CefBytesWriter(size_t grow)
    : grow_(grow), datasize_(grow), offset_(0) {
  DCHECK(grow > 0);
  data_ = malloc(grow);
  DCHECK(data_ != nullptr);
}

CefBytesWriter::~CefBytesWriter() {
  base::AutoLock lock_scope(lock_);
  if (data_)
    free(data_);
}

size_t CefBytesWriter::Write(const void* ptr, size_t size, size_t n) {
  base::AutoLock lock_scope(lock_);
  size_t rv;
  if (offset_ + static_cast<int64>(size * n) >= datasize_ &&
      Grow(size * n) == 0) {
    rv = 0;
  } else {
    memcpy(reinterpret_cast<char*>(data_) + offset_, ptr, size * n);
    offset_ += size * n;
    rv = n;
  }

  return rv;
}

int CefBytesWriter::Seek(int64 offset, int whence) {
  int rv = -1L;
  base::AutoLock lock_scope(lock_);
  switch (whence) {
    case SEEK_CUR:
      if (offset_ + offset > datasize_ || offset_ + offset < 0)
        break;
      offset_ += offset;
      rv = 0;
      break;
    case SEEK_END: {
      int64 offset_abs = std::abs(offset);
      if (offset_abs > datasize_)
        break;
      offset_ = datasize_ - offset_abs;
      rv = 0;
      break;
    }
    case SEEK_SET:
      if (offset > datasize_ || offset < 0)
        break;
      offset_ = offset;
      rv = 0;
      break;
  }

  return rv;
}

int64 CefBytesWriter::Tell() {
  base::AutoLock lock_scope(lock_);
  return offset_;
}

int CefBytesWriter::Flush() {
  return 0;
}

std::string CefBytesWriter::GetDataString() {
  base::AutoLock lock_scope(lock_);
  std::string str(reinterpret_cast<char*>(data_), offset_);
  return str;
}

size_t CefBytesWriter::Grow(size_t size) {
  base::AutoLock lock_scope(lock_);
  size_t rv;
  size_t s = (size > grow_ ? size : grow_);
  void* tmp = realloc(data_, datasize_ + s);
  DCHECK(tmp != nullptr);
  if (tmp) {
    data_ = tmp;
    datasize_ += s;
    rv = datasize_;
  } else {
    rv = 0;
  }

  return rv;
}
