//========================================================================
//
// CachedFile.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2009 Stefan Thomas <thomas@eload24.com>
// Copyright 2010, 2011 Hib Eris <hib@hiberis.nl>
// Copyright 2010 Albert Astals Cid <aacid@kde.org>
//
//========================================================================

#include <config.h>
#include "CachedFile.h"

//------------------------------------------------------------------------
// CachedFile
//------------------------------------------------------------------------

CachedFile::CachedFile(CachedFileLoader *cachedFileLoaderA, GooString *uriA)
{
  uri = uriA;
  loader = cachedFileLoaderA;

  streamPos = 0;
  chunks = new std::vector<Chunk>();
  length = 0;

  length = loader->init(uri, this);
  refCnt = 1;

  if (length != ((size_t) -1)) {
    chunks->resize(length/CachedFileChunkSize + 1);
  }
  else {
    error(-1, "Failed to initialize file cache for '%s'.", uri->getCString());
    chunks->resize(0);
  }
}

CachedFile::~CachedFile()
{
  delete uri;
  delete loader;
  delete chunks;
}

void CachedFile::incRefCnt() {
  refCnt++;
}

void CachedFile::decRefCnt() {
  if (--refCnt == 0)
    delete this;
}

long int CachedFile::tell() {
  return streamPos;
}

int CachedFile::seek(long int offset, int origin)
{
  if (origin == SEEK_SET) {
    streamPos = offset;
  } else if (origin == SEEK_CUR) {
    streamPos += offset;
  } else {
    streamPos = length + offset;
  }

  if (streamPos > length) {
    streamPos = 0;
    return 1;
  }

  return 0;
}

int CachedFile::cache(const std::vector<ByteRange> &origRanges)
{
  std::vector<int> loadChunks;
  int numChunks = length/CachedFileChunkSize + 1;
  std::vector<bool> chunkNeeded(numChunks);
  int startChunk, endChunk;
  std::vector<ByteRange> chunk_ranges, all;
  ByteRange range;
  const std::vector<ByteRange> *ranges = &origRanges;

  if (ranges->empty()) {
    range.offset = 0;
    range.length = length;
    all.push_back(range);
    ranges = &all;
  }

  for (int i = 0; i < numChunks; ++i)
    chunkNeeded[i] = false;
  for (size_t i = 0; i < ranges->size(); i++) {

    if ((*ranges)[i].length == 0) continue;
    if ((*ranges)[i].offset >= length) continue;

    size_t start = (*ranges)[i].offset;
    size_t end = start + (*ranges)[i].length - 1;
    if (end >= length) end = length - 1;

    startChunk = start / CachedFileChunkSize;
    endChunk = end / CachedFileChunkSize;
    for (int chunk = startChunk; chunk <= endChunk; chunk++) {
      if ((*chunks)[chunk].state == chunkStateNew) {
           chunkNeeded[chunk] = true;
      }
    }
  }

  int chunk = 0;
  while (chunk < numChunks) {
    while (!chunkNeeded[chunk] && (++chunk != numChunks)) ;
    if (chunk == numChunks) break;
    startChunk = chunk;
    loadChunks.push_back(chunk);

    while ((++chunk != numChunks) && chunkNeeded[chunk]) {
      loadChunks.push_back(chunk);
    }
    endChunk = chunk - 1;

    range.offset = startChunk * CachedFileChunkSize;
    range.length = (endChunk - startChunk + 1) * CachedFileChunkSize;

    chunk_ranges.push_back(range);
  }

  if (chunk_ranges.size() > 0) {
    CachedFileWriter writer =
        CachedFileWriter(this, &loadChunks);
    return loader->load(chunk_ranges, &writer);
  }

  return 0;
}

size_t CachedFile::read(void *ptr, size_t unitsize, size_t count)
{
  size_t bytes = unitsize*count;
  if (length < (streamPos + bytes)) {
    bytes = length - streamPos;
  }

  if (bytes == 0) return 0;

  // Load data
  if (cache(streamPos, bytes) != 0) return 0;

  // Copy data to buffer
  size_t toCopy = bytes;
  while (toCopy) {
    int chunk = streamPos / CachedFileChunkSize;
    int offset = streamPos % CachedFileChunkSize;
    size_t len = CachedFileChunkSize-offset;

    if (len > toCopy)
      len = toCopy;

    memcpy(ptr, (*chunks)[chunk].data + offset, len);
    streamPos += len;
    toCopy -= len;
    ptr = (char*)ptr + len;
  }

  return bytes;
}

int CachedFile::cache(size_t offset, size_t length)
{
  std::vector<ByteRange> r;
  ByteRange range;
  range.offset = offset;
  range.length = length;
  r.push_back(range);
  return cache(r);
}

//------------------------------------------------------------------------
// CachedFileWriter
//------------------------------------------------------------------------

CachedFileWriter::CachedFileWriter(CachedFile *cachedFileA, std::vector<int> *chunksA)
{
   cachedFile = cachedFileA;
   chunks = chunksA;

   if (chunks) {
     offset = 0;
     it = (*chunks).begin();
   }
}

CachedFileWriter::~CachedFileWriter()
{
}

size_t CachedFileWriter::write(const char *ptr, size_t size)
{
  const char *cp = ptr;
  size_t len = size;
  size_t nfree, ncopy;
  size_t written = 0;
  size_t chunk;

  if (!len) return 0;

  while (len) {
    if (chunks) {
      if (offset == CachedFileChunkSize) {
         it++;
         if (it == (*chunks).end()) return written;
         offset = 0;
      }
      chunk = *it;
    } else {
      offset = cachedFile->length % CachedFileChunkSize;
      chunk = cachedFile->length / CachedFileChunkSize;
    }

    if (chunk >= cachedFile->chunks->size()) {
       cachedFile->chunks->resize(chunk + 1);
    }

    nfree = CachedFileChunkSize - offset;
    ncopy = (len >= nfree) ? nfree : len;
    memcpy(&((*cachedFile->chunks)[chunk].data[offset]), cp, ncopy);
    len -= ncopy;
    cp += ncopy;
    offset += ncopy;
    written += ncopy;

    if (!chunks) {
      cachedFile->length += ncopy;
    }

    if (offset == CachedFileChunkSize) {
       (*cachedFile->chunks)[chunk].state = CachedFile::chunkStateLoaded;
    }
  }

  if ((chunk == (cachedFile->length / CachedFileChunkSize)) &&
      (offset == (cachedFile->length % CachedFileChunkSize))) {
     (*cachedFile->chunks)[chunk].state = CachedFile::chunkStateLoaded;
  }

  return written;
}

//------------------------------------------------------------------------

