// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "courgette/encoded_program.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <vector>

#include "base/cxx17_backports.h"
#include "courgette/image_utils.h"
#include "courgette/label_manager.h"
#include "courgette/streams.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace courgette {

namespace {

// Helper class to instantiate RVAToLabel while managing allocation.
class TestLabelManager : public LabelManager {
 public:
  void RawAddLabel(int index, RVA rva) {
    labels_.push_back(Label(rva, index));  // Don't care about |count_|.
  }
};

// Creates a simple new program with given addresses. The orders of elements
// in |abs32_specs| and |rel32_specs| are important.
std::unique_ptr<EncodedProgram> CreateTestProgram(
    const TestLabelManager& abs32_label_manager,
    const TestLabelManager& rel32_label_manager) {
  std::unique_ptr<EncodedProgram> program(new EncodedProgram());

  uint32_t base = 0x00900000;
  program->set_image_base(base);

  EXPECT_TRUE(program->ImportLabels(abs32_label_manager, rel32_label_manager));

  EXPECT_TRUE(program->AddOrigin(0));  // Start at base.

  // Add instructions. Since we're using TestLabelManager, Labels are sorted in
  // the order they're added via Add().
  for (const Label& label : abs32_label_manager.Labels())
    EXPECT_TRUE(program->AddAbs32(label.index_));
  for (const Label& label : rel32_label_manager.Labels())
    EXPECT_TRUE(program->AddRel32(label.index_));

  return program;
}

bool CompareSink(const uint8_t expected[],
                 size_t num_expected,
                 SinkStream* ss) {
  size_t n = ss->Length();
  if (num_expected != n)
    return false;
  const uint8_t* buffer = ss->Buffer();
  return memcmp(&expected[0], buffer, n) == 0;
}

}  // namespace

// Create a simple program with a few addresses and references and
// check that the bits produced are as expected.
TEST(EncodedProgramTest, Test) {
  // ABS32 index 7 <-- base + 4.
  TestLabelManager abs32_label_manager;
  abs32_label_manager.RawAddLabel(7, 4);
  // REL32 index 5 <-- base + 0.
  TestLabelManager rel32_label_manager;
  rel32_label_manager.RawAddLabel(5, 0);

  std::unique_ptr<EncodedProgram> program(
      CreateTestProgram(abs32_label_manager, rel32_label_manager));

  // Serialize and deserialize.
  SinkStreamSet sinks;
  EXPECT_TRUE(program->WriteTo(&sinks));
  program.reset();

  SinkStream sink;
  bool can_collect = sinks.CopyTo(&sink);
  EXPECT_TRUE(can_collect);

  const void* buffer = sink.Buffer();
  size_t length = sink.Length();

  SourceStreamSet sources;
  bool can_get_source_streams = sources.Init(buffer, length);
  EXPECT_TRUE(can_get_source_streams);

  std::unique_ptr<EncodedProgram> encoded2(new EncodedProgram());
  bool can_read = encoded2->ReadFrom(&sources);
  EXPECT_TRUE(can_read);

  // Finally, try to assemble.
  SinkStream assembled;
  bool can_assemble = encoded2->AssembleTo(&assembled);
  EXPECT_TRUE(can_assemble);
  encoded2.reset();

  const uint8_t golden[] = {
      0x04, 0x00, 0x90,
      0x00,  // ABS32 to base + 4
      0xF8, 0xFF, 0xFF,
      0xFF  // REL32 from next line to base + 2
  };
  EXPECT_TRUE(CompareSink(golden, base::size(golden), &assembled));
}

// A larger test with multiple addresses. We encode the program and check the
// contents of the address streams.
TEST(EncodedProgramTest, TestWriteAddress) {
  // Absolute addresses by index: [_, _, _, 2, _, 23, _, 11].
  TestLabelManager abs32_label_manager;
  abs32_label_manager.RawAddLabel(7, 11);
  abs32_label_manager.RawAddLabel(3, 2);
  abs32_label_manager.RawAddLabel(5, 23);
  // Relative addresses by index: [16, 7, _, 32].
  TestLabelManager rel32_label_manager;
  rel32_label_manager.RawAddLabel(0, 16);
  rel32_label_manager.RawAddLabel(3, 32);
  rel32_label_manager.RawAddLabel(1, 7);

  std::unique_ptr<EncodedProgram> program(
      CreateTestProgram(abs32_label_manager, rel32_label_manager));

  SinkStreamSet sinks;
  EXPECT_TRUE(program->WriteTo(&sinks));
  program.reset();

  // Check indexes and addresses in sinks.
  const uint8_t golden_abs32_indexes[] = {
      0x03, 0x07, 0x03, 0x05  // 3 indexes: [7, 3, 5].
  };
  EXPECT_TRUE(CompareSink(golden_abs32_indexes,
                          base::size(golden_abs32_indexes),
                          sinks.stream(kStreamAbs32Indexes)));

  const uint8_t golden_rel32_indexes[] = {
      0x03, 0x00, 0x03, 0x01  // 3 indexes: [0, 3, 1].
  };
  EXPECT_TRUE(CompareSink(golden_rel32_indexes,
                          base::size(golden_rel32_indexes),
                          sinks.stream(kStreamRel32Indexes)));

  // Addresses: [_, _, _, 2, _, 23, _, 11].
  // Padded:    [0, 0, 0, 2, 2, 23, 23, 11].
  // Delta:     [0, 0, 0, 2, 0, 21, 0, -12].
  // Hex:       [0, 0, 0, 0x02, 0, 0x15, 0, 0xFFFFFFF4].
  // Complement neg:  [0, 0, 0, 0x02, 0, 0x15, 0, (0x0B)].
  // Varint32 Signed: [0, 0, 0, 0x04, 0, 0x2A, 0, 0x17].
  const uint8_t golden_abs32_addresses[] = {
      0x08,  // 8 address deltas.
      0x00, 0x00, 0x00, 0x04, 0x00, 0x2A, 0x00, 0x17,
  };
  EXPECT_TRUE(CompareSink(golden_abs32_addresses,
                          base::size(golden_abs32_addresses),
                          sinks.stream(kStreamAbs32Addresses)));

  // Addresses: [16, 7, _, 32].
  // Padded:    [16, 7, 7, 32].
  // Delta:     [16, -9, 0, 25].
  // Hex:       [0x10, 0xFFFFFFF7, 0, 0x19].
  // Complement Neg:  [0x10, (0x08), 0, 0x19].
  // Varint32 Signed: [0x20, 0x11, 0, 0x32].
  const uint8_t golden_rel32_addresses[] = {
      0x04,  // 4 address deltas.
      0x20, 0x11, 0x00, 0x32,
  };
  EXPECT_TRUE(CompareSink(golden_rel32_addresses,
                          base::size(golden_rel32_addresses),
                          sinks.stream(kStreamRel32Addresses)));
}

}  // namespace courgette
