/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/system_wrappers/source/file_impl.h"

#include <assert.h>

#ifdef _WIN32
#include <Windows.h>
#else
#include <stdarg.h>
#include <string.h>
#endif

#include "webrtc/base/checks.h"
#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"

namespace webrtc {

FileWrapper* FileWrapper::Create() {
  return new FileWrapperImpl();
}

FileWrapperImpl::FileWrapperImpl()
    : rw_lock_(RWLockWrapper::CreateRWLock()),
      id_(NULL),
      managed_file_handle_(true),
      open_(false),
      looping_(false),
      read_only_(false),
      max_size_in_bytes_(0),
      size_in_bytes_(0) {
  memset(file_name_utf8_, 0, kMaxFileNameSize);
}

FileWrapperImpl::~FileWrapperImpl() {
  if (id_ != NULL && managed_file_handle_) {
    fclose(id_);
  }
}

int FileWrapperImpl::CloseFile() {
  WriteLockScoped write(*rw_lock_);
  return CloseFileImpl();
}

int FileWrapperImpl::Rewind() {
  WriteLockScoped write(*rw_lock_);
  if (looping_ || !read_only_) {
    if (id_ != NULL) {
      size_in_bytes_ = 0;
      return fseek(id_, 0, SEEK_SET);
    }
  }
  return -1;
}

int FileWrapperImpl::SetMaxFileSize(size_t bytes) {
  WriteLockScoped write(*rw_lock_);
  max_size_in_bytes_ = bytes;
  return 0;
}

int FileWrapperImpl::Flush() {
  WriteLockScoped write(*rw_lock_);
  return FlushImpl();
}

int FileWrapperImpl::FileName(char* file_name_utf8, size_t size) const {
  ReadLockScoped read(*rw_lock_);
  size_t length = strlen(file_name_utf8_);
  if (length > kMaxFileNameSize) {
    assert(false);
    return -1;
  }
  if (length < 1) {
    return -1;
  }

  // Make sure to NULL terminate
  if (size < length) {
    length = size - 1;
  }
  memcpy(file_name_utf8, file_name_utf8_, length);
  file_name_utf8[length] = 0;
  return 0;
}

bool FileWrapperImpl::Open() const {
  ReadLockScoped read(*rw_lock_);
  return open_;
}

int FileWrapperImpl::OpenFile(const char* file_name_utf8, bool read_only,
                              bool loop, bool text) {
  WriteLockScoped write(*rw_lock_);
  if (id_ != NULL && !managed_file_handle_)
    return -1;
  size_t length = strlen(file_name_utf8);
  if (length > kMaxFileNameSize - 1) {
    return -1;
  }

  read_only_ = read_only;

  FILE* tmp_id = NULL;
#if defined _WIN32
  wchar_t wide_file_name[kMaxFileNameSize];
  wide_file_name[0] = 0;

  MultiByteToWideChar(CP_UTF8,
                      0,  // UTF8 flag
                      file_name_utf8,
                      -1,  // Null terminated string
                      wide_file_name,
                      kMaxFileNameSize);
  if (text) {
    if (read_only) {
      tmp_id = _wfopen(wide_file_name, L"rt");
    } else {
      tmp_id = _wfopen(wide_file_name, L"wt");
    }
  } else {
    if (read_only) {
      tmp_id = _wfopen(wide_file_name, L"rb");
    } else {
      tmp_id = _wfopen(wide_file_name, L"wb");
    }
  }
#else
  if (text) {
    if (read_only) {
      tmp_id = fopen(file_name_utf8, "rt");
    } else {
      tmp_id = fopen(file_name_utf8, "wt");
    }
  } else {
    if (read_only) {
      tmp_id = fopen(file_name_utf8, "rb");
    } else {
      tmp_id = fopen(file_name_utf8, "wb");
    }
  }
#endif

  if (tmp_id != NULL) {
    // +1 comes from copying the NULL termination character.
    memcpy(file_name_utf8_, file_name_utf8, length + 1);
    if (id_ != NULL) {
      fclose(id_);
    }
    id_ = tmp_id;
    managed_file_handle_ = true;
    looping_ = loop;
    open_ = true;
    return 0;
  }
  return -1;
}

int FileWrapperImpl::OpenFromFileHandle(FILE* handle,
                                        bool manage_file,
                                        bool read_only,
                                        bool loop) {
  WriteLockScoped write(*rw_lock_);
  if (!handle)
    return -1;

  if (id_ != NULL) {
    if (managed_file_handle_)
      fclose(id_);
    else
      return -1;
  }

  id_ = handle;
  managed_file_handle_ = manage_file;
  read_only_ = read_only;
  looping_ = loop;
  open_ = true;
  return 0;
}

int FileWrapperImpl::Read(void* buf, size_t length) {
  WriteLockScoped write(*rw_lock_);
  if (id_ == NULL)
    return -1;

  size_t bytes_read = fread(buf, 1, length, id_);
  if (bytes_read != length && !looping_) {
    CloseFileImpl();
  }
  return static_cast<int>(bytes_read);
}

int FileWrapperImpl::WriteText(const char* format, ...) {
  WriteLockScoped write(*rw_lock_);
  if (format == NULL)
    return -1;

  if (read_only_)
    return -1;

  if (id_ == NULL)
    return -1;

  va_list args;
  va_start(args, format);
  int num_chars = vfprintf(id_, format, args);
  va_end(args);

  if (num_chars >= 0) {
    return num_chars;
  } else {
    CloseFileImpl();
    return -1;
  }
}

bool FileWrapperImpl::Write(const void* buf, size_t length) {
  WriteLockScoped write(*rw_lock_);
  if (buf == NULL)
    return false;

  if (read_only_)
    return false;

  if (id_ == NULL)
    return false;

  // Check if it's time to stop writing.
  if (max_size_in_bytes_ > 0 &&
      (size_in_bytes_ + length) > max_size_in_bytes_) {
    FlushImpl();
    return false;
  }

  size_t num_bytes = fwrite(buf, 1, length, id_);
  if (num_bytes > 0) {
    size_in_bytes_ += num_bytes;
    return true;
  }

  CloseFileImpl();
  return false;
}

int FileWrapperImpl::CloseFileImpl() {
  if (id_ != NULL) {
    if (managed_file_handle_)
      fclose(id_);
    id_ = NULL;
  }
  memset(file_name_utf8_, 0, kMaxFileNameSize);
  open_ = false;
  return 0;
}

int FileWrapperImpl::FlushImpl() {
  if (id_ != NULL) {
    return fflush(id_);
  }
  return -1;
}

int FileWrapper::Rewind() {
  DCHECK(false);
  return -1;
}

}  // namespace webrtc
