/*
 * Copyright 2011 Google Inc. 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
 *
 *      http://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 "sfntly/data/readable_font_data.h"

#include <stdio.h>

#include <limits>

#include "sfntly/data/memory_byte_array.h"
#include "sfntly/data/writable_font_data.h"
#include "sfntly/port/exception_type.h"

namespace sfntly {

ReadableFontData::ReadableFontData(ByteArray* array)
    : FontData(array),
      checksum_set_(false),
      checksum_(0) {
}

ReadableFontData::~ReadableFontData() {}

// TODO(arthurhsu): re-investigate the memory model of this function.  It's
//                  not too useful without copying, but it's not performance
//                  savvy to do copying.
CALLER_ATTACH
ReadableFontData* ReadableFontData::CreateReadableFontData(ByteVector* b) {
  assert(b);
  ByteArrayPtr ba = new MemoryByteArray(b->size());
  ba->Put(0, b);
  ReadableFontDataPtr wfd = new ReadableFontData(ba);
  return wfd.Detach();
}

int64_t ReadableFontData::Checksum() {
  AutoLock lock(checksum_lock_);
  if (!checksum_set_) {
    ComputeChecksum();
  }
  return checksum_;
}

void ReadableFontData::SetCheckSumRanges(const IntegerList& ranges) {
  checksum_range_ = ranges;
  checksum_set_ = false;  // UNIMPLEMENTED: atomicity
}

int32_t ReadableFontData::ReadUByte(int32_t index) {
  int32_t b = array_->Get(BoundOffset(index));
  if (b < 0) {
#if !defined (SFNTLY_NO_EXCEPTION)
    throw IndexOutOfBoundException(
        "Index attempted to be read from is out of bounds", index);
#endif
    return kInvalidUnsigned;
  }
  return b;
}

int32_t ReadableFontData::ReadByte(int32_t index) {
  int32_t b = array_->Get(BoundOffset(index));
  if (b < 0) {
#if !defined (SFNTLY_NO_EXCEPTION)
    throw IndexOutOfBoundException(
        "Index attempted to be read from is out of bounds", index);
#endif
    return kInvalidByte;
  }
  return (b << 24) >> 24;
}

int32_t ReadableFontData::ReadBytes(int32_t index,
                                    byte_t* b,
                                    int32_t offset,
                                    int32_t length) {
  return array_->Get(BoundOffset(index), b, offset, BoundLength(index, length));
}

int32_t ReadableFontData::ReadChar(int32_t index) {
  return ReadUByte(index);
}

int32_t ReadableFontData::ReadUShort(int32_t index) {
  int32_t b1 = ReadUByte(index);
  if (b1 < 0)
    return kInvalidUnsigned;
  int32_t b2 = ReadUByte(index + 1);
  if (b2 < 0)
    return kInvalidUnsigned;
  return 0xffff & (b1 << 8 | b2);
}

int32_t ReadableFontData::ReadShort(int32_t index) {
  int32_t b1 = ReadByte(index);
  if (b1 == kInvalidByte)
    return kInvalidShort;
  int32_t b2 = ReadUByte(index + 1);
  if (b2 < 0)
    return kInvalidShort;

  uint32_t result = static_cast<uint32_t>(b1) << 8 | b2;
  return static_cast<int32_t>(result << 16) >> 16;
}

int32_t ReadableFontData::ReadUInt24(int32_t index) {
  int32_t b1 = ReadUByte(index);
  if (b1 < 0)
    return kInvalidUnsigned;
  int32_t b2 = ReadUByte(index + 1);
  if (b2 < 0)
    return kInvalidUnsigned;
  int32_t b3 = ReadUByte(index + 2);
  if (b3 < 0)
    return kInvalidUnsigned;
  return 0xffffff & (b1 << 16 | b2 << 8 | b3);
}

int64_t ReadableFontData::ReadULong(int32_t index) {
  int32_t b1 = ReadUByte(index);
  if (b1 < 0)
    return kInvalidUnsigned;
  int32_t b2 = ReadUByte(index + 1);
  if (b2 < 0)
    return kInvalidUnsigned;
  int32_t b3 = ReadUByte(index + 2);
  if (b3 < 0)
    return kInvalidUnsigned;
  int32_t b4 = ReadUByte(index + 3);
  if (b4 < 0)
    return kInvalidUnsigned;
  return 0xffffffffL & (b1 << 24 | b2 << 16 | b3 << 8 | b4);
}

int32_t ReadableFontData::ReadULongAsInt(int32_t index) {
  int64_t ulong = ReadULong(index);
#if !defined (SFNTLY_NO_EXCEPTION)
  if ((ulong & 0x80000000) == 0x80000000) {
    throw ArithmeticException("Long value too large to fit into an integer.");
  }
#endif
  return static_cast<int32_t>(ulong);
}

int64_t ReadableFontData::ReadULongLE(int32_t index) {
  int32_t b1 = ReadUByte(index);
  if (b1 < 0)
    return kInvalidUnsigned;
  int32_t b2 = ReadUByte(index + 1);
  if (b2 < 0)
    return kInvalidUnsigned;
  int32_t b3 = ReadUByte(index + 2);
  if (b3 < 0)
    return kInvalidUnsigned;
  int32_t b4 = ReadUByte(index + 3);
  if (b4 < 0)
    return kInvalidUnsigned;
  return 0xffffffffL & (b1 | b2 << 8 | b3 << 16 | b4 << 24);
}

int32_t ReadableFontData::ReadLong(int32_t index) {
  int32_t b1 = ReadByte(index);
  if (b1 == kInvalidByte)
    return kInvalidLong;
  int32_t b2 = ReadUByte(index + 1);
  if (b2 < 0)
    return kInvalidLong;
  int32_t b3 = ReadUByte(index + 2);
  if (b3 < 0)
    return kInvalidLong;
  int32_t b4 = ReadUByte(index + 3);
  if (b4 < 0)
    return kInvalidLong;
  return static_cast<uint32_t>(b1) << 24 | b2 << 16 | b3 << 8 | b4;
}

int32_t ReadableFontData::ReadFixed(int32_t index) {
  return ReadLong(index);
}

int64_t ReadableFontData::ReadDateTimeAsLong(int32_t index) {
  int32_t high = ReadULong(index);
  if (high == kInvalidUnsigned)
    return kInvalidLongDateTime;
  int32_t low = ReadULong(index + 4);
  if (low == kInvalidUnsigned)
    return kInvalidLongDateTime;
  return (int64_t)high << 32 | low;
}

int32_t ReadableFontData::ReadFWord(int32_t index) {
  return ReadShort(index);
}

int32_t ReadableFontData::ReadFUFWord(int32_t index) {
  return ReadUShort(index);
}

int32_t ReadableFontData::CopyTo(OutputStream* os) {
  return array_->CopyTo(os, BoundOffset(0), Length());
}

int32_t ReadableFontData::CopyTo(WritableFontData* wfd) {
  return array_->CopyTo(wfd->BoundOffset(0),
                        wfd->array_,
                        BoundOffset(0),
                        Length());
}

int32_t ReadableFontData::CopyTo(ByteArray* ba) {
  return array_->CopyTo(ba, BoundOffset(0), Length());
}

int32_t ReadableFontData::SearchUShort(int32_t start_index,
                                       int32_t start_offset,
                                       int32_t end_index,
                                       int32_t end_offset,
                                       int32_t length,
                                       int32_t key) {
  int32_t location = 0;
  int32_t bottom = 0;
  int32_t top = length;
  while (top != bottom) {
    location = (top + bottom) / 2;
    int32_t location_start = ReadUShort(start_index + location * start_offset);
    if (key < location_start) {
      // location is below current location
      top = location;
    } else {
      // is key below the upper bound?
      int32_t location_end = ReadUShort(end_index + location * end_offset);
#if defined (SFNTLY_DEBUG_FONTDATA)
      fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end);
#endif
      if (key <= location_end)
        return location;

      // location is above the current location
      bottom = location + 1;
    }
  }
  return -1;
}

int32_t ReadableFontData::SearchUShort(int32_t start_index,
                                       int32_t start_offset,
                                       int32_t length,
                                       int32_t key) {
  int32_t location = 0;
  int32_t bottom = 0;
  int32_t top = length;
  while (top != bottom) {
    location = (top + bottom) / 2;
    int32_t location_start = ReadUShort(start_index + location * start_offset);
    if (key == location_start)
      return location;

    if (key < location_start) {
      // location is below current location
      top = location;
    } else {
      // location is above current location
      bottom = location + 1;
    }
  }
  return -1;
}

int32_t ReadableFontData::SearchULong(int32_t start_index,
                                      int32_t start_offset,
                                      int32_t end_index,
                                      int32_t end_offset,
                                      int32_t length,
                                      int32_t key) {
  int32_t location = 0;
  int32_t bottom = 0;
  int32_t top = length;
  while (top != bottom) {
    location = (top + bottom) / 2;
    int32_t location_start = ReadULongAsInt(start_index
                                            + location * start_offset);
    if (key < location_start) {
      // location is below current location
      top = location;
    } else {
      // is key below the upper bound?
      int32_t location_end = ReadULongAsInt(end_index + location * end_offset);
#if defined (SFNTLY_DEBUG_FONTDATA)
      fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end);
#endif
      if (key <= location_end)
        return location;

      // location is above the current location
      bottom = location + 1;
    }
  }
  return -1;
}

CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset,
                                                int32_t length) {
  if (offset < 0 || length < 0 ||
      offset > std::numeric_limits<int32_t>::max() - length ||
      offset + length > Size()) {
#if !defined (SFNTLY_NO_EXCEPTION)
    throw IndexOutOfBoundsException(
        "Attempt to bind data outside of its limits");
#endif
    return NULL;
  }
  FontDataPtr slice = new ReadableFontData(this, offset, length);
  return slice.Detach();
}

CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset) {
  if (offset < 0 || offset > Size()) {
#if !defined (SFNTLY_NO_EXCEPTION)
    throw IndexOutOfBoundsException(
        "Attempt to bind data outside of its limits");
#endif
    return NULL;
  }
  FontDataPtr slice = new ReadableFontData(this, offset);
  return slice.Detach();
}

ReadableFontData::ReadableFontData(ReadableFontData* data, int32_t offset)
    : FontData(data, offset),
      checksum_set_(false),
      checksum_(0) {
}

ReadableFontData::ReadableFontData(ReadableFontData* data,
                                   int32_t offset,
                                   int32_t length)
    : FontData(data, offset, length),
      checksum_set_(false),
      checksum_(0) {
}

void ReadableFontData::ComputeChecksum() {
  // TODO(arthurhsu): IMPLEMENT: synchronization/atomicity
  int64_t sum = 0;
  if (checksum_range_.empty()) {
    sum = ComputeCheckSum(0, Length());
  } else {
    for (uint32_t low_bound_index = 0; low_bound_index < checksum_range_.size();
         low_bound_index += 2) {
      int32_t low_bound = checksum_range_[low_bound_index];
      int32_t high_bound = (low_bound_index == checksum_range_.size() - 1) ?
                                Length() :
                                checksum_range_[low_bound_index + 1];
      sum += ComputeCheckSum(low_bound, high_bound);
    }
  }

  checksum_ = sum & 0xffffffffL;
  checksum_set_ = true;
}

int64_t ReadableFontData::ComputeCheckSum(int32_t low_bound,
                                          int32_t high_bound) {
  int64_t sum = 0;
  // Checksum all whole 4-byte chunks.
  for (int32_t i = low_bound; i <= high_bound - 4; i += 4) {
    sum += ReadULong(i);
  }

  // Add last fragment if not 4-byte multiple
  int32_t off = high_bound & -4;
  if (off < high_bound) {
    int32_t b3 = ReadUByte(off);
    int32_t b2 = (off + 1 < high_bound) ? ReadUByte(off + 1) : 0;
    int32_t b1 = (off + 2 < high_bound) ? ReadUByte(off + 2) : 0;
    int32_t b0 = 0;
    sum += (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
  }
  return sum;
}

}  // namespace sfntly
