// 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 "headerparser.h"
#include "logging.h"
#include "varint_bigendian.h"
#include "vcdiff_defs.h"

namespace open_vcdiff {

// *** Methods for ParseableChunk

void ParseableChunk::Advance(size_t number_of_bytes) {
  if (number_of_bytes > UnparsedSize()) {
    LOG(DFATAL) << "Internal error: position advanced by " << number_of_bytes
                << " bytes, current unparsed size " << UnparsedSize()
                << LOG_ENDL;
    position_ = end_;
    return;
  }
  position_ += number_of_bytes;
}

void ParseableChunk::SetPosition(const char* position) {
  if (position < start_) {
    LOG(DFATAL) << "Internal error: new data position " << position
                << " is beyond start of data " << start_ << LOG_ENDL;
    position_ = start_;
    return;
  }
  if (position > end_) {
    LOG(DFATAL) << "Internal error: new data position " << position
                << " is beyond end of data " << end_ << LOG_ENDL;
    position_ = end_;
    return;
  }
  position_ = position;
}

void ParseableChunk::FinishExcept(size_t number_of_bytes) {
  if (number_of_bytes > UnparsedSize()) {
    LOG(DFATAL) << "Internal error: specified number of remaining bytes "
                << number_of_bytes << " is greater than unparsed data size "
                << UnparsedSize() << LOG_ENDL;
    Finish();
    return;
  }
  position_ = end_ - number_of_bytes;
}

// *** Methods for VCDiffHeaderParser

VCDiffHeaderParser::VCDiffHeaderParser(const char* header_start,
                                       const char* data_end)
    : parseable_chunk_(header_start, data_end - header_start),
      return_code_(RESULT_SUCCESS),
      delta_encoding_length_(0),
      delta_encoding_start_(NULL) { }

bool VCDiffHeaderParser::ParseByte(unsigned char* value) {
  if (RESULT_SUCCESS != return_code_) {
    return false;
  }
  if (parseable_chunk_.Empty()) {
    return_code_ = RESULT_END_OF_DATA;
    return false;
  }
  *value = static_cast<unsigned char>(*parseable_chunk_.UnparsedData());
  parseable_chunk_.Advance(1);
  return true;
}

bool VCDiffHeaderParser::ParseInt32(const char* variable_description,
                                    int32_t* value) {
  if (RESULT_SUCCESS != return_code_) {
    return false;
  }
  int32_t parsed_value =
      VarintBE<int32_t>::Parse(parseable_chunk_.End(),
                               parseable_chunk_.UnparsedDataAddr());
  switch (parsed_value) {
    case RESULT_ERROR:
      LOG(ERROR) << "Expected " << variable_description
                 << "; found invalid variable-length integer" << LOG_ENDL;
      return_code_ = RESULT_ERROR;
      return false;
    case RESULT_END_OF_DATA:
      return_code_ = RESULT_END_OF_DATA;
      return false;
    default:
      *value = parsed_value;
      return true;
  }
}

// When an unsigned 32-bit integer is expected, parse a signed 64-bit value
// instead, then check the value limit.  The uint32_t type can't be parsed
// directly because two negative values are given special meanings (RESULT_ERROR
// and RESULT_END_OF_DATA) and could not be expressed in an unsigned format.
bool VCDiffHeaderParser::ParseUInt32(const char* variable_description,
                                     uint32_t* value) {
  if (RESULT_SUCCESS != return_code_) {
    return false;
  }
  int64_t parsed_value =
      VarintBE<int64_t>::Parse(parseable_chunk_.End(),
                               parseable_chunk_.UnparsedDataAddr());
  switch (parsed_value) {
    case RESULT_ERROR:
      LOG(ERROR) << "Expected " << variable_description
                 << "; found invalid variable-length integer" << LOG_ENDL;
      return_code_ = RESULT_ERROR;
      return false;
    case RESULT_END_OF_DATA:
      return_code_ = RESULT_END_OF_DATA;
      return false;
    default:
      if (parsed_value > 0xFFFFFFFF) {
        LOG(ERROR) << "Value of " << variable_description << "(" << parsed_value
                   << ") is too large for unsigned 32-bit integer" << LOG_ENDL;
        return_code_ = RESULT_ERROR;
        return false;
      }
      *value = static_cast<uint32_t>(parsed_value);
      return true;
  }
}

// A VCDChecksum represents an unsigned 32-bit value returned by adler32(),
// but isn't a uint32_t.
bool VCDiffHeaderParser::ParseChecksum(const char* variable_description,
                                       VCDChecksum* value) {
  uint32_t parsed_value = 0;
  if (!ParseUInt32(variable_description, &parsed_value)) {
    return false;
  }
  *value = static_cast<VCDChecksum>(parsed_value);
  return true;
}

bool VCDiffHeaderParser::ParseSize(const char* variable_description,
                                   size_t* value) {
  int32_t parsed_value = 0;
  if (!ParseInt32(variable_description, &parsed_value)) {
    return false;
  }
  *value = static_cast<size_t>(parsed_value);
  return true;
}

bool VCDiffHeaderParser::ParseSourceSegmentLengthAndPosition(
    size_t from_size,
    const char* from_boundary_name,
    const char* from_name,
    size_t* source_segment_length,
    size_t* source_segment_position) {
  // Verify the length and position values
  if (!ParseSize("source segment length", source_segment_length)) {
    return false;
  }
  // Guard against overflow by checking source length first
  if (*source_segment_length > from_size) {
    LOG(ERROR) << "Source segment length (" << *source_segment_length
               << ") is larger than " << from_name << " (" << from_size
               << ")" << LOG_ENDL;
    return_code_ = RESULT_ERROR;
    return false;
  }
  if (!ParseSize("source segment position", source_segment_position)) {
    return false;
  }
  if ((*source_segment_position >= from_size) &&
      (*source_segment_length > 0)) {
    LOG(ERROR) << "Source segment position (" << *source_segment_position
               << ") is past " << from_boundary_name
               << " (" << from_size << ")" << LOG_ENDL;
    return_code_ = RESULT_ERROR;
    return false;
  }
  const size_t source_segment_end = *source_segment_position +
                                    *source_segment_length;
  if (source_segment_end > from_size) {
    LOG(ERROR) << "Source segment end position (" << source_segment_end
               << ") is past " << from_boundary_name
               << " (" << from_size << ")" << LOG_ENDL;
    return_code_ = RESULT_ERROR;
    return false;
  }
  return true;
}

bool VCDiffHeaderParser::ParseWinIndicatorAndSourceSegment(
    size_t dictionary_size,
    size_t decoded_target_size,
    bool allow_vcd_target,
    unsigned char* win_indicator,
    size_t* source_segment_length,
    size_t* source_segment_position) {
  if (!ParseByte(win_indicator)) {
    return false;
  }
  unsigned char source_target_flags =
      *win_indicator & (VCD_SOURCE | VCD_TARGET);
  switch (source_target_flags) {
    case VCD_SOURCE:
      return ParseSourceSegmentLengthAndPosition(dictionary_size,
                                                 "end of dictionary",
                                                 "dictionary",
                                                 source_segment_length,
                                                 source_segment_position);
    case VCD_TARGET:
      if (!allow_vcd_target) {
        LOG(ERROR) << "Delta file contains VCD_TARGET flag, which is not "
                      "allowed by current decoder settings" << LOG_ENDL;
        return_code_ = RESULT_ERROR;
        return false;
      }
      return ParseSourceSegmentLengthAndPosition(decoded_target_size,
                                                 "current target position",
                                                 "target file",
                                                 source_segment_length,
                                                 source_segment_position);
    case VCD_SOURCE | VCD_TARGET:
      LOG(ERROR) << "Win_Indicator must not have both VCD_SOURCE"
                    " and VCD_TARGET set" << LOG_ENDL;
      return_code_ = RESULT_ERROR;
      return false;
    default:
      return true;
  }
}

bool VCDiffHeaderParser::ParseWindowLengths(size_t* target_window_length) {
  if (delta_encoding_start_) {
    LOG(DFATAL) << "Internal error: VCDiffHeaderParser::ParseWindowLengths "
                   "was called twice for the same delta window" << LOG_ENDL;
    return_code_ = RESULT_ERROR;
    return false;
  }
  if (!ParseSize("length of the delta encoding", &delta_encoding_length_)) {
    return false;
  }
  delta_encoding_start_ = UnparsedData();
  if (!ParseSize("size of the target window", target_window_length)) {
    return false;
  }
  return true;
}

const char* VCDiffHeaderParser::EndOfDeltaWindow() const {
  if (!delta_encoding_start_) {
    LOG(DFATAL) << "Internal error: VCDiffHeaderParser::GetDeltaWindowEnd "
                   "was called before ParseWindowLengths" << LOG_ENDL;
    return NULL;
  }
  return delta_encoding_start_ + delta_encoding_length_;
}

bool VCDiffHeaderParser::ParseDeltaIndicator() {
  unsigned char delta_indicator;
  if (!ParseByte(&delta_indicator)) {
    return false;
  }
  if (delta_indicator & (VCD_DATACOMP | VCD_INSTCOMP | VCD_ADDRCOMP)) {
    LOG(ERROR) << "Secondary compression of delta file sections "
                  "is not supported" << LOG_ENDL;
    return_code_ = RESULT_ERROR;
    return false;
  }
  return true;
}

bool VCDiffHeaderParser::ParseSectionLengths(
    bool has_checksum,
    size_t* add_and_run_data_length,
    size_t* instructions_and_sizes_length,
    size_t* addresses_length,
    VCDChecksum* checksum) {
  ParseSize("length of data for ADDs and RUNs", add_and_run_data_length);
  ParseSize("length of instructions section", instructions_and_sizes_length);
  ParseSize("length of addresses for COPYs", addresses_length);
  if (has_checksum) {
    ParseChecksum("Adler32 checksum value", checksum);
  }
  if (RESULT_SUCCESS != return_code_) {
    return false;
  }
  if (!delta_encoding_start_) {
    LOG(DFATAL) << "Internal error: VCDiffHeaderParser::ParseSectionLengths "
                   "was called before ParseWindowLengths" << LOG_ENDL;
    return_code_ = RESULT_ERROR;
    return false;
  }
  const size_t delta_encoding_header_length =
      UnparsedData() - delta_encoding_start_;
  if (delta_encoding_length_ !=
          (delta_encoding_header_length +
           *add_and_run_data_length +
           *instructions_and_sizes_length +
           *addresses_length)) {
    LOG(ERROR) << "The length of the delta encoding does not match "
                  "the size of the header plus the sizes of the data sections"
               << LOG_ENDL;
    return_code_ = RESULT_ERROR;
    return false;
  }
  return true;
}

}  // namespace open_vcdiff
