// Copyright 2008 Google Inc.
// Author: Lincoln Smith
//
// 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 <config.h>
#include "encodetable.h"
#include <string>
#include "addrcache.h"
#include "codetable.h"
#include "instruction_map.h"
#include "logging.h"
#include "google/output_string.h"
#include "varint_bigendian.h"
#include "vcdiff_defs.h"

namespace open_vcdiff {

// VCDiffCodeTableWriter members and methods

// If interleaved is true, the encoder writes each delta file window
// by interleaving instructions and sizes with their corresponding
// addresses and data, rather than placing these elements into three
// separate sections.  This facilitates providing partially
// decoded results when only a portion of a delta file window
// is received (e.g. when HTTP over TCP is used as the
// transmission protocol.)  The interleaved format is
// not consistent with the VCDIFF draft standard.
//
VCDiffCodeTableWriter::VCDiffCodeTableWriter(bool interleaved)
    : max_mode_(VCDiffAddressCache::DefaultLastMode()),
      dictionary_size_(0),
      target_length_(0),
      code_table_data_(&VCDiffCodeTableData::kDefaultCodeTableData),
      instruction_map_(NULL),
      last_opcode_index_(-1),
      add_checksum_(false),
      checksum_(0),
      match_counts_(kMaxMatchSize, 0) {
  InitSectionPointers(interleaved);
}

VCDiffCodeTableWriter::VCDiffCodeTableWriter(
    bool interleaved,
    int near_cache_size,
    int same_cache_size,
    const VCDiffCodeTableData& code_table_data,
    unsigned char max_mode)
    : max_mode_(max_mode),
      address_cache_(near_cache_size, same_cache_size),
      dictionary_size_(0),
      target_length_(0),
      code_table_data_(&code_table_data),
      instruction_map_(NULL),
      last_opcode_index_(-1),
      add_checksum_(false),
      checksum_(0)  {
  InitSectionPointers(interleaved);
}

VCDiffCodeTableWriter::~VCDiffCodeTableWriter() {
  if (code_table_data_ != &VCDiffCodeTableData::kDefaultCodeTableData) {
    delete instruction_map_;
  }
}

void VCDiffCodeTableWriter::InitSectionPointers(bool interleaved) {
  if (interleaved) {
    data_for_add_and_run_ = &instructions_and_sizes_;
    addresses_for_copy_ = &instructions_and_sizes_;
  } else {
    data_for_add_and_run_ = &separate_data_for_add_and_run_;
    addresses_for_copy_ = &separate_addresses_for_copy_;
  }
}

bool VCDiffCodeTableWriter::Init(size_t dictionary_size) {
  dictionary_size_ = dictionary_size;
  if (!instruction_map_) {
    if (code_table_data_ == &VCDiffCodeTableData::kDefaultCodeTableData) {
      instruction_map_ = VCDiffInstructionMap::GetDefaultInstructionMap();
    } else {
      instruction_map_ = new VCDiffInstructionMap(*code_table_data_, max_mode_);
    }
    if (!instruction_map_) {
      return false;
    }
  }
  if (!address_cache_.Init()) {
    return false;
  }
  target_length_ = 0;
  last_opcode_index_ = -1;
  return true;
}

// The VCDiff format allows each opcode to represent either
// one or two delta instructions.  This function will first
// examine the opcode generated by the last call to EncodeInstruction.
// If that opcode was a single-instruction opcode, this function checks
// whether there is a compound (double-instruction) opcode that can
// combine that single instruction with the instruction that is now
// being added, and so save a byte of space.  In that case, the
// single-instruction opcode at position last_opcode_index_ will be
// overwritten with the new double-instruction opcode.
//
// In the majority of cases, no compound opcode will be possible,
// and a new single-instruction opcode will be appended to
// instructions_and_sizes_, followed by a representation of its size
// if the opcode does not implicitly give the instruction size.
//
// As an example, say instructions_and_sizes_ contains 10 bytes, the last
// of which contains the opcode 0x02 (ADD size 1).  Because that was the
// most recently added opcode, last_opcode_index_ has the value 10.
// EncodeInstruction is then called with inst = VCD_COPY, size = 4, mode = 0.
// The function will replace the old opcode 0x02 with the double-instruction
// opcode 0xA3 (ADD size 1 + COPY size 4 mode 0).
//
// All of the double-instruction opcodes in the standard code table
// have implicit sizes, meaning that the size of the instruction will not
// need to be written to the instructions_and_sizes_ string separately
// from the opcode.  If a custom code table were used that did not have
// this property, then instructions_and_sizes_ might contain a
// double-instruction opcode (say, COPY size 0 mode 0 + ADD size 0)
// followed by the size of the COPY, then by the size of the ADD.
// If using the SDCH interleaved format, the address of the COPY instruction
// would follow its size, so the ordering would be
// [Compound Opcode][Size of COPY][Address of COPY][Size of ADD]
//
void VCDiffCodeTableWriter::EncodeInstruction(VCDiffInstructionType inst,
                                              size_t size,
                                              unsigned char mode) {
  if (!instruction_map_) {
    LOG(DFATAL) << "EncodeInstruction() called without calling Init()"
                << LOG_ENDL;
    return;
  }
  if (last_opcode_index_ >= 0) {
    const unsigned char last_opcode =
        instructions_and_sizes_[last_opcode_index_];
    // The encoding engine should not generate two ADD instructions in a row.
    // This won't cause a failure, but it's inefficient encoding and probably
    // represents a bug in the higher-level logic of the encoder.
    if ((inst == VCD_ADD) &&
        (code_table_data_->inst1[last_opcode] == VCD_ADD)) {
      LOG(WARNING) << "EncodeInstruction() called for two ADD instructions"
                      " in a row" << LOG_ENDL;
    }
    OpcodeOrNone compound_opcode = kNoOpcode;
    if (size <= UCHAR_MAX) {
      compound_opcode =
          instruction_map_->LookupSecondOpcode(last_opcode,
                                               inst,
                                               static_cast<unsigned char>(size),
                                               mode);
      if (compound_opcode != kNoOpcode) {
        instructions_and_sizes_[last_opcode_index_] =
            static_cast<unsigned char>(compound_opcode);
        last_opcode_index_ = -1;
        return;
      }
    }
    // Try finding a compound opcode with size 0.
    compound_opcode = instruction_map_->LookupSecondOpcode(last_opcode,
                                                           inst,
                                                           0,
                                                           mode);
    if (compound_opcode != kNoOpcode) {
      instructions_and_sizes_[last_opcode_index_] =
          static_cast<unsigned char>(compound_opcode);
      last_opcode_index_ = -1;
      AppendSizeToString(size, &instructions_and_sizes_);
      return;
    }
  }
  OpcodeOrNone opcode = kNoOpcode;
  if (size <= UCHAR_MAX) {
    opcode =
        instruction_map_->LookupFirstOpcode(inst,
                                            static_cast<unsigned char>(size),
                                            mode);
    if (opcode != kNoOpcode) {
      instructions_and_sizes_.push_back(static_cast<char>(opcode));
      last_opcode_index_ = static_cast<int>(instructions_and_sizes_.size() - 1);
      return;
    }
  }
  // There should always be an opcode with size 0.
  opcode = instruction_map_->LookupFirstOpcode(inst, 0, mode);
  if (opcode == kNoOpcode) {
    LOG(DFATAL) << "No matching opcode found for inst " << inst
                << ", mode " << mode << ", size 0" << LOG_ENDL;
    return;
  }
  instructions_and_sizes_.push_back(static_cast<char>(opcode));
  last_opcode_index_ = static_cast<int>(instructions_and_sizes_.size() - 1);
  AppendSizeToString(size, &instructions_and_sizes_);
}

void VCDiffCodeTableWriter::Add(const char* data, size_t size) {
  EncodeInstruction(VCD_ADD, size);
  data_for_add_and_run_->append(data, size);
  target_length_ += size;
}

void VCDiffCodeTableWriter::Copy(int32_t offset, size_t size) {
  if (!instruction_map_) {
    LOG(DFATAL) << "VCDiffCodeTableWriter::Copy() called without calling Init()"
                << LOG_ENDL;
    return;
  }
  // If a single interleaved stream of encoded values is used
  // instead of separate sections for instructions, addresses, and data,
  // then the string instructions_and_sizes_ may be the same as
  // addresses_for_copy_.  The address should therefore be encoded
  // *after* the instruction and its size.
  int32_t encoded_addr = 0;
  const unsigned char mode = address_cache_.EncodeAddress(
      offset,
      static_cast<VCDAddress>(dictionary_size_ + target_length_),
      &encoded_addr);
  EncodeInstruction(VCD_COPY, size, mode);
  if (address_cache_.WriteAddressAsVarintForMode(mode)) {
    VarintBE<int32_t>::AppendToString(encoded_addr, addresses_for_copy_);
  } else {
    addresses_for_copy_->push_back(static_cast<unsigned char>(encoded_addr));
  }
  target_length_ += size;
  if (size >= match_counts_.size()) {
    match_counts_.resize(size * 2, 0);  // Be generous to avoid resizing again
  }
  ++match_counts_[size];
}

void VCDiffCodeTableWriter::Run(size_t size, unsigned char byte) {
  EncodeInstruction(VCD_RUN, size);
  data_for_add_and_run_->push_back(byte);
  target_length_ += size;
}

size_t VCDiffCodeTableWriter::CalculateLengthOfSizeAsVarint(size_t size) {
  return VarintBE<int32_t>::Length(static_cast<int32_t>(size));
}

void VCDiffCodeTableWriter::AppendSizeToString(size_t size, string* out) {
  VarintBE<int32_t>::AppendToString(static_cast<int32_t>(size), out);
}

void VCDiffCodeTableWriter::AppendSizeToOutputString(
    size_t size,
    OutputStringInterface* out) {
  VarintBE<int32_t>::AppendToOutputString(static_cast<int32_t>(size), out);
}

// This calculation must match the items added between "Start of Delta Encoding"
// and "End of Delta Encoding" in Output(), below.
size_t VCDiffCodeTableWriter::CalculateLengthOfTheDeltaEncoding() const {
  size_t length_of_the_delta_encoding =
    CalculateLengthOfSizeAsVarint(target_length_) +
    1 +  // Delta_Indicator
    CalculateLengthOfSizeAsVarint(separate_data_for_add_and_run_.size()) +
    CalculateLengthOfSizeAsVarint(instructions_and_sizes_.size()) +
    CalculateLengthOfSizeAsVarint(separate_addresses_for_copy_.size()) +
    separate_data_for_add_and_run_.size() +
    instructions_and_sizes_.size() +
    separate_addresses_for_copy_.size();
  if (add_checksum_) {
    length_of_the_delta_encoding +=
        VarintBE<int64_t>::Length(static_cast<int64_t>(checksum_));
  }
  return length_of_the_delta_encoding;
}

void VCDiffCodeTableWriter::Output(OutputStringInterface* out) {
  if (instructions_and_sizes_.empty()) {
    LOG(WARNING) << "Empty input; no delta window produced" << LOG_ENDL;
  } else {
    const size_t length_of_the_delta_encoding =
        CalculateLengthOfTheDeltaEncoding();
    const size_t delta_window_size =
        length_of_the_delta_encoding +
        1 +  // Win_Indicator
        CalculateLengthOfSizeAsVarint(dictionary_size_) +
        CalculateLengthOfSizeAsVarint(0) +
        CalculateLengthOfSizeAsVarint(length_of_the_delta_encoding);
    // append() will be called many times on the output string; make sure
    // the output string is resized only once at most.
    out->ReserveAdditionalBytes(delta_window_size);

    // Add first element: Win_Indicator
    if (add_checksum_) {
      out->push_back(VCD_SOURCE | VCD_CHECKSUM);
    } else {
      out->push_back(VCD_SOURCE);
    }
    // Source segment size: dictionary size
    AppendSizeToOutputString(dictionary_size_, out);
    // Source segment position: 0 (start of dictionary)
    AppendSizeToOutputString(0, out);

    // [Here is where a secondary compressor would be used
    //  if the encoder and decoder supported that feature.]

    AppendSizeToOutputString(length_of_the_delta_encoding, out);
    // Start of Delta Encoding
    const size_t size_before_delta_encoding = out->size();
    AppendSizeToOutputString(target_length_, out);
    out->push_back(0x00);  // Delta_Indicator: no compression
    AppendSizeToOutputString(separate_data_for_add_and_run_.size(), out);
    AppendSizeToOutputString(instructions_and_sizes_.size(), out);
    AppendSizeToOutputString(separate_addresses_for_copy_.size(), out);
    if (add_checksum_) {
      // The checksum is a 32-bit *unsigned* integer.  VarintBE requires a
      // signed type, so use a 64-bit signed integer to store the checksum.
      VarintBE<int64_t>::AppendToOutputString(static_cast<int64_t>(checksum_),
                                              out);
    }
    out->append(separate_data_for_add_and_run_.data(),
                separate_data_for_add_and_run_.size());
    out->append(instructions_and_sizes_.data(),
                instructions_and_sizes_.size());
    out->append(separate_addresses_for_copy_.data(),
                separate_addresses_for_copy_.size());
    // End of Delta Encoding
    const size_t size_after_delta_encoding = out->size();
    if (length_of_the_delta_encoding !=
        (size_after_delta_encoding - size_before_delta_encoding)) {
      LOG(DFATAL) << "Internal error: calculated length of the delta encoding ("
                  << length_of_the_delta_encoding
                  << ") does not match actual length ("
                  << (size_after_delta_encoding - size_before_delta_encoding)
                  << LOG_ENDL;
    }
    separate_data_for_add_and_run_.clear();
    instructions_and_sizes_.clear();
    separate_addresses_for_copy_.clear();
    if (target_length_ == 0) {
      LOG(WARNING) << "Empty target window" << LOG_ENDL;
    }
  }

  // Reset state for next window; assume we are using same code table
  // and dictionary.  The caller will have to invoke Init() if a different
  // dictionary is used.
  //
  // Notably, Init() calls address_cache_.Init().  This resets the address
  // cache between delta windows, as required by RFC section 5.1.
  if (!Init(dictionary_size_)) {
    LOG(DFATAL) << "Internal error: calling Init() to reset "
                   "VCDiffCodeTableWriter state failed" << LOG_ENDL;
  }
}

};  // namespace open_vcdiff
