// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "testing/fake_file_access.h"

#include <utility>

#include "core/fxcrt/check.h"
#include "core/fxcrt/fx_system.h"

class FileAccessWrapper final : public FPDF_FILEACCESS {
 public:
  explicit FileAccessWrapper(FakeFileAccess* simulator)
      : simulator_(simulator) {
    m_FileLen = simulator_->GetFileSize();
    m_GetBlock = &GetBlockImpl;
    m_Param = this;
  }

  static int GetBlockImpl(void* param,
                          unsigned long position,
                          unsigned char* pBuf,
                          unsigned long size) {
    return static_cast<FileAccessWrapper*>(param)->simulator_->GetBlock(
        position, pBuf, size);
  }

 private:
  UnownedPtr<FakeFileAccess> simulator_;
};

class FileAvailImpl final : public FX_FILEAVAIL {
 public:
  explicit FileAvailImpl(FakeFileAccess* simulator) : simulator_(simulator) {
    version = 1;
    IsDataAvail = &IsDataAvailImpl;
  }

  static FPDF_BOOL IsDataAvailImpl(FX_FILEAVAIL* pThis,
                                   size_t offset,
                                   size_t size) {
    return static_cast<FileAvailImpl*>(pThis)->simulator_->IsDataAvail(offset,
                                                                       size);
  }

 private:
  UnownedPtr<FakeFileAccess> simulator_;
};

class DownloadHintsImpl final : public FX_DOWNLOADHINTS {
 public:
  explicit DownloadHintsImpl(FakeFileAccess* simulator)
      : simulator_(simulator) {
    version = 1;
    AddSegment = &AddSegmentImpl;
  }

  static void AddSegmentImpl(FX_DOWNLOADHINTS* pThis,
                             size_t offset,
                             size_t size) {
    return static_cast<DownloadHintsImpl*>(pThis)->simulator_->AddSegment(
        offset, size);
  }

 private:
  UnownedPtr<FakeFileAccess> simulator_;
};

FakeFileAccess::FakeFileAccess(FPDF_FILEACCESS* file_access)
    : file_access_(file_access),
      file_access_wrapper_(std::make_unique<FileAccessWrapper>(this)),
      file_avail_(std::make_unique<FileAvailImpl>(this)),
      download_hints_(std::make_unique<DownloadHintsImpl>(this)) {
  DCHECK(file_access_);
}

FakeFileAccess::~FakeFileAccess() = default;

FPDF_FILEACCESS* FakeFileAccess::GetFileAccess() const {
  return file_access_wrapper_.get();
}

FX_FILEAVAIL* FakeFileAccess::GetFileAvail() const {
  return file_avail_.get();
}

FX_DOWNLOADHINTS* FakeFileAccess::GetDownloadHints() const {
  return download_hints_.get();
}

FPDF_BOOL FakeFileAccess::IsDataAvail(size_t offset, size_t size) const {
  return available_data_.Contains(RangeSet::Range(offset, offset + size));
}

void FakeFileAccess::AddSegment(size_t offset, size_t size) {
  requested_data_.Union(RangeSet::Range(offset, offset + size));
}

unsigned long FakeFileAccess::GetFileSize() {
  return file_access_->m_FileLen;
}

int FakeFileAccess::GetBlock(unsigned long position,
                             unsigned char* pBuf,
                             unsigned long size) {
  if (!pBuf || !size)
    return false;

  if (!IsDataAvail(static_cast<size_t>(position), static_cast<size_t>(size)))
    return false;

  return file_access_->m_GetBlock(file_access_->m_Param, position, pBuf, size);
}

void FakeFileAccess::SetRequestedDataAvailable() {
  available_data_.Union(requested_data_);
  requested_data_.Clear();
}

void FakeFileAccess::SetWholeFileAvailable() {
  available_data_.Union(RangeSet::Range(0, static_cast<size_t>(GetFileSize())));
  requested_data_.Clear();
}
