// 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.

#ifndef OPEN_VCDIFF_VCDECODER_TEST_H_
#define OPEN_VCDIFF_VCDECODER_TEST_H_

#include "google/vcdecoder.h"
#include <string>
#include "checksum.h"
#include "testing.h"

namespace open_vcdiff {

// A base class used for all the decoder tests.  Most tests use the same
// dictionary and target and construct the delta file in the same way.
// Those elements are provided as string members and can be modified or
// overwritten by each specific decoder test as needed.
class VCDiffDecoderTest : public testing::Test {
 protected:
  typedef std::string string;

  static const char kDictionary[];
  static const char kExpectedTarget[];

  VCDiffDecoderTest();

  virtual ~VCDiffDecoderTest() {}

  virtual void SetUp();

  // These functions populate delta_file_header_ with a standard or interleaved
  // file header.
  void UseStandardFileHeader();
  void UseInterleavedFileHeader();

  // This function is called by SetUp().  It populates delta_file_ with the
  // concatenated delta file header, delta window header, and delta window
  // body, plus (if UseChecksum() is true) the corresponding checksum.
  // It can be called again by a test that has modified the contents of
  // delta_file_ and needs to restore them to their original state.
  virtual void InitializeDeltaFile();

  // This function adds an Adler32 checksum to the delta window header.
  void AddChecksum(VCDChecksum checksum);

  // This function computes the Adler32 checksum for the expected target
  // and adds it to the delta window header.
  void ComputeAndAddChecksum();

  // Write the maximum expressible positive 32-bit VarintBE
  // (0x7FFFFFFF) at the given offset in the delta window.
  void WriteMaxVarintAtOffset(int offset, int bytes_to_replace);

  // Write a negative 32-bit VarintBE (0x80000000) at the given offset
  // in the delta window.
  void WriteNegativeVarintAtOffset(int offset, int bytes_to_replace);

  // Write a VarintBE that has too many continuation bytes
  // at the given offset in the delta window.
  void WriteInvalidVarintAtOffset(int offset, int bytes_to_replace);

  // This function iterates through a list of fuzzers (bit masks used to corrupt
  // bytes) and through positions in the delta file.  Each time it is called, it
  // attempts to corrupt a different byte in delta_file_ in a different way.  If
  // successful, it returns true. Once it exhausts the list of fuzzers and of
  // byte positions in delta_file_, it returns false.
  bool FuzzOneByteInDeltaFile();

  // Assuming the length of the given string can be expressed as a VarintBE
  // of length N, this function returns the byte at position which_byte, where
  // 0 <= which_byte < N.
  static char GetByteFromStringLength(const char* s, int which_byte);

  // Assuming the length of the given string can be expressed as a one-byte
  // VarintBE, this function returns that byte value.
  static char StringLengthAsByte(const char* s) {
    return GetByteFromStringLength(s, 0);
  }

  // Assuming the length of the given string can be expressed as a two-byte
  // VarintBE, this function returns the first byte of its representation.
  static char FirstByteOfStringLength(const char* s) {
    return GetByteFromStringLength(s, 0);
  }

  // Assuming the length of the given string can be expressed as a two-byte
  // VarintBE, this function returns the second byte of its representation.
  static char SecondByteOfStringLength(const char* s) {
    return GetByteFromStringLength(s, 1);
  }

  VCDiffStreamingDecoder decoder_;

  // delta_file_ will be populated by InitializeDeltaFile() using the components
  // delta_file_header_, delta_window_header_, and delta_window_body_.
  string delta_file_;

  // This string is not populated during setup, but is used to receive the
  // decoded target file in each test.
  string output_;

  // Test fixtures that inherit from VCDiffDecoderTest can set these strings in
  // their constructors to override their default values (which come from
  // kDictionary, kExpectedTarget, etc.)
  string dictionary_;
  string expected_target_;

  // The components that will be used to construct delta_file_.
  string delta_file_header_;
  string delta_window_header_;
  string delta_window_body_;

 private:
  // These values should only be accessed via UseStandardFileHeader() and
  // UseInterleavedFileHeader().
  static const char kStandardFileHeader[];
  static const char kInterleavedFileHeader[];

  // These two counters are used by FuzzOneByteInDeltaFile() to iterate through
  // different ways to corrupt the delta file.
  size_t fuzzer_;
  size_t fuzzed_byte_position_;
};

// The "standard" decoder test, which decodes a delta file that uses the
// standard VCDIFF (RFC 3284) format with no extensions.
class VCDiffStandardDecoderTest : public VCDiffDecoderTest {
 protected:
  VCDiffStandardDecoderTest();
  virtual ~VCDiffStandardDecoderTest() {}

 private:
  static const char kWindowHeader[];
  static const char kWindowBody[];
};

class VCDiffInterleavedDecoderTest : public VCDiffDecoderTest {
 protected:
  VCDiffInterleavedDecoderTest();
  virtual ~VCDiffInterleavedDecoderTest() {}

 private:
  static const char kWindowHeader[];
  static const char kWindowBody[];
};

}  // namespace open_vcdiff

#endif  // OPEN_VCDIFF_VCDECODER_TEST_H_
